Powershell 递归函数中属性值的缩短输出

Powershell 递归函数中属性值的缩短输出,powershell,namespaces,wmi,Powershell,Namespaces,Wmi,我想递归枚举所有WMI命名空间。我有以下函数: function Get-WmiNamespace { Param( [parameter()] [string]$Namespace = 'root', [parameter()] [string]$Locale = 'MS_409', [parameter()] [switch]$Recurse ) Begin { $WMIParams = @{ Namespa

我想递归枚举所有WMI命名空间。我有以下函数:

function Get-WmiNamespace {
  Param(
    [parameter()]
    [string]$Namespace = 'root',
    [parameter()]
    [string]$Locale = 'MS_409',
    [parameter()]
    [switch]$Recurse
    )
  Begin {
    $WMIParams = @{
      Namespace = $Namespace
      Class = '__NAMESPACE'
      Locale = $Locale
      ErrorAction = 'SilentlyContinue'
      }
    }
  Process {
    Get-WmiObject @WMIParams |
      Sort-Object -Property Name -CaseSensitive -Culture "en-US" |
        ForEach-Object {
          $WMIParams.Namespace = "{0}\{1}" -f $_.__NAMESPACE, $_.Name
          $object = [PSCustomObject] @{
            Namespace = $WMIParams.Namespace
            }
          $object.PSTypeNames.Insert(0,'Wmi.Namespace.Name')
          $object
          if ($recurse) {
            $PSBoundParameters.Namespace = $WMIParams.Namespace
            Get-WMINamespace @PSBoundParameters
            }
          }
    }
  }
灵感来源于此: [https://learn-powershell.net/2014/05/09/quick-hits-list-all-available-wmi-namespaces-using-powershell/]

我得到这个输出:

Namespace
---------
ROOT\Appv
ROOT\CIMV2
ROOT\CIMV2\mdm
ROOT\CIMV2\mdm\dmmap
ROOT\CIMV2\mdm\MS_405
ROOT\CIMV2\ms_405
ROOT\CIMV2\ms_409
ROOT\CIMV2\power
ROOT\CIMV2\power\m...
ROOT\CIMV2\power\m...
ROOT\CIMV2\Security
ROOT\CIMV2\Securit...
ROOT\CIMV2\Securit...
ROOT\CIMV2\Termina...
ROOT\CIMV2\Termina...
ROOT\Cli
ROOT\Cli\MS_405
ROOT\Cli\MS_409
ROOT\DEFAULT
ROOT\DEFAULT\ms_405
ROOT\DEFAULT\ms_409
ROOT\directory
ROOT\directory\LDAP
ROOT\directory\LDA...
ROOT\directory\LDA...
ROOT\Hardware
ROOT\Hardware\ms_405
ROOT\Hardware\ms_409
ROOT\Intel_ME
ROOT\IntelNCS2
ROOT\IntelNCS2\ms_409
ROOT\Interop
ROOT\Interop\ms_405
ROOT\Interop\ms_409
ROOT\Microsoft
ROOT\Microsoft\Hom...
ROOT\Microsoft\pro...
ROOT\Microsoft\Sec...
ROOT\Microsoft\Uev
ROOT\Microsoft\Win...
...
ROOT\Microsoft\Win...
ROOT\msdtc
ROOT\PEH
ROOT\Policy
ROOT\Policy\ms_405
ROOT\Policy\ms_409
ROOT\RSOP
ROOT\RSOP\Computer
ROOT\RSOP\User
ROOT\SECURITY
ROOT\SecurityCenter
ROOT\SecurityCenter2
ROOT\ServiceModel
ROOT\StandardCimv2
ROOT\StandardCimv2...
ROOT\StandardCimv2...
ROOT\StandardCimv2...
ROOT\StandardCimv2...
ROOT\subscription
ROOT\subscription\...
ROOT\subscription\...
ROOT\WMI
ROOT\WMI\ms_405
ROOT\WMI\ms_409
名称空间名称被截断。 我猜原因是Name列的宽度是在函数Get WmiNamespace的第一次迭代中根据最长值ROOT\SecurityCenter2设置的

可以通过管道输出将其固定为带有-AutoSize参数的表格格式:

Namespace
---------
ROOT\Appv
ROOT\CIMV2
ROOT\CIMV2\mdm
ROOT\CIMV2\mdm\dmmap
ROOT\CIMV2\mdm\MS_405
ROOT\CIMV2\ms_405
ROOT\CIMV2\ms_409
ROOT\CIMV2\power
ROOT\CIMV2\power\ms_405
ROOT\CIMV2\power\ms_409
ROOT\CIMV2\Security
ROOT\CIMV2\Security\MicrosoftTpm
ROOT\CIMV2\Security\MicrosoftVolumeEncryption
ROOT\CIMV2\TerminalServices
ROOT\CIMV2\TerminalServices\ms_405
ROOT\Cli
ROOT\Cli\MS_405
ROOT\Cli\MS_409
...

解决此行为的最佳方法是什么?

整个名称存储在namespace属性中。如果您只想在命令输出中看到它,可以从选择对象中使用-ExpandProperty

获取WmiNamespace-Recurse | select-ExpandProperty命名空间

此外,只需添加Sort即可显示全名

Get-WmiNamespace -Recurse | Sort

道格指出,如果不使用Expand和Doug,您可以将其点上,避免格式问题,或者尝试更改函数本身,等等。至少对于单个列来说是这样

(Get-WmiNamespace -Recurse).Namespace
# Results
<#
 (Get-WmiNamespace -Recurse).Namespace
ROOT\Appv
...
ROOT\CIMV2\Security\MicrosoftTpm
ROOT\CIMV2\Security\MicrosoftVolumeEncryption
ROOT\CIMV2\TerminalServices
ROOT\CIMV2\TerminalServices\ms_409
...

ROOT\Microsoft\SqlServer\ComputerManagement15
ROOT\Microsoft\SqlServer\ComputerManagement15\MS_409
ROOT\Microsoft\SqlServer\ServerEvents
ROOT\Microsoft\SqlServer\ServerEvents\MSSQLSERVER
...
ROOT\Microsoft\Windows\DesiredStateConfigurationProxy
ROOT\Microsoft\Windows\DesiredStateConfigurationProxy\MS_409
...
#>
因此,要使此列表获得类似于表的视图,请执行相同的操作

Get-WmiNamespace -Recurse | 
Format-Wide -Property namespace -Column 3
# Results
<#
ROOT\Appv                                              ROOT\aspnet                                            ROOT\CIMV2                                           
ROOT\CIMV2\mdm                                         ROOT\CIMV2\mdm\dmmap                                   ROOT\CIMV2\mdm\MS_409                                
ROOT\CIMV2\ms_409                                      ROOT\CIMV2\NV                                          ROOT\CIMV2\NV\Events  
....
#>
使用适合您屏幕的任何列计数。不,不能同时使用列和自动调整大小,因为它们是互斥的

所以,正如Doug指出的,您可以制作自己的格式化程序,或者根据您的评论


“我的观点是,是否有办法修改函数本身以获得 表格格式'


…您可以对函数进行修改,以便将上述内容用于所需的结果。

FWIW实际上是格式化表首先截断了这些值:我的观点是,当控制台上有足够的可用水平空间且无需修改时,是否有办法修改函数本身,以在不缩短表格式的情况下对其进行格式化需要通过下一个格式表或其他任何形式传递。您可以创建自己的自定义格式
Get-WmiNamespace -Recurse | 
Format-Wide -Property namespace -Column 3
# Results
<#
ROOT\Appv                                              ROOT\aspnet                                            ROOT\CIMV2                                           
ROOT\CIMV2\mdm                                         ROOT\CIMV2\mdm\dmmap                                   ROOT\CIMV2\mdm\MS_409                                
ROOT\CIMV2\ms_409                                      ROOT\CIMV2\NV                                          ROOT\CIMV2\NV\Events  
....
#>