如何将目录对象转换为字符串 - Powershell

cyn*_*n77 3 windows string powershell type-conversion

我有一组从某些注册表查询中检索到的路径。截至目前,它们仍然作为目录对象返回,但我需要将它们转换为字符串数组。在 PS 中执行此操作最有效的方法是什么?

代码:

  $found_paths = @();

  $uninstall_keys = getRegistrySubkeys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" '\\Office[\d+.*]';
  if ($uninstall_keys -ne $null) 
  {
    foreach ($key in $uninstall_keys)
    {
      $product_name = getRegistryValue $key "DisplayName";
      $version = getRegistryValue $key "DisplayVersion";
      $base_install_path = getRegistryValue $key "InstallLocation"; 
      $full_install_path = Get-ChildItem -Directory -LiteralPath $base_install_path | Where-Object Name -match '^Office\d{1,2}\D?' | Select-Object FullName;

      $found_paths += ,$full_install_path
    }
  }

  write-output $found_paths; 
Run Code Online (Sandbox Code Playgroud)

输出:

 FullName                                          
--------                                          
C:\Program Files\Microsoft Office Servers\OFFICE15
C:\Program Files\Microsoft Office\Office15        
Run Code Online (Sandbox Code Playgroud)

期望的输出:

C:\Program Files\Microsoft Office Servers\OFFICE15
C:\Program Files\Microsoft Office\Office15  
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 6

有效的方法是使用成员访问枚举( (...).PropName):

$full_install_path = (
  Get-ChildItem -Directory -LiteralPath $base_install_path | Where-Object Name -match '^Office\d{1,2}\D?'
).FullName
Run Code Online (Sandbox Code Playgroud)

注意:听起来您的命令可能只返回一个目录信息对象,但该方法也适用于多个目录信息对象,在这种情况下会返回一路径。

您需要处理的对象越多,成员访问枚举相对于解决方案的速度优势就越大(见下文)。Select-Object -ExpandProperty


至于你尝试过的

... | Select-Object FullName
Run Code Online (Sandbox Code Playgroud)

不返回输入对象属性的.FullName,它返回一个具有包含该值的属性[pscustomobject]的实例.FullName 。要仅获取值,您需要使用... | Select-Object -ExpandProperty FullName

$found_paths += , $full_install_path
Run Code Online (Sandbox Code Playgroud)

您可能的意思是$found_paths += $full_install_path- 无需首先在 RHS 上构造一个数组(使用)。,

事实上,如果您这样做并且$full_install_path碰巧包含多个元素,您将得到一个嵌套数组。

退后一步:让 PowerShell 自动为您收集数组中循环语句的输出会更高效

  $uninstall_keys = getRegistrySubkeys "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" '\\Office[\d+.*]'
  if ($null -ne $uninstall_keys) 
  {
    # Collect the `foreach` loop's outputs in an array.
    [array] $found_paths = foreach ($key in $uninstall_keys)
    {
      $product_name = getRegistryValue $key "DisplayName"
      $version = getRegistryValue $key "DisplayVersion"
      $base_install_path = getRegistryValue $key "InstallLocation"
      # Get and output the full path.
      (Get-ChildItem -Directory -LiteralPath $base_install_path | Where-Object Name -match '^Office\d{1,2}\D?').FullName
    }
  }

  $found_paths # output (implicit equivalent of Write-Output $found_paths
Run Code Online (Sandbox Code Playgroud)