在输出报告中显示列 Headers 一次
Displaying Column Headers Once in Output Report
我正在使用 PowerCLI 编写一个脚本来审计公司虚拟环境中的磁盘分区类型。到目前为止我得到了这个代码:
$report = @()
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
foreach ($VM in $VMs){
$vmName = $VM.Name
$output = Invoke-VMScript -ScriptText @'
Get-Disk |
select @{ l="ComputerName"; e={ $env:COMPUTERNAME } },
Number,
@{ name='Size'; expr={[int]($_.Size/1GB)} },
PartitionStyle
'@ -VM $vmName -GuestUser $Username -GuestPassword $Password
$output.ScriptOutput #printing each for testing
$report += $output.ScriptOutput
}
$report | FT -AutoSize
这将产生如下所示的输出:
ComputerName
Number
Size
PartitionStyle
VMNAME1
0
100
MBR
VMNAME1
1
20
GPT
VMNAME1
2
20
MBR
ComputerName
Number
Size
PartitionStyle
VMNAME2
0
100
MBR
VMNAME2
1
20
GPT
我面临的问题是输出报告中每个虚拟机都重复了 headers 列。我怎样才能解决这个问题,只显示一次 headers 列,如下所示:
ComputerName
Number
Size
PartitionStyle
VMNAME1
0
100
MBR
VMNAME1
1
20
GPT
VMNAME1
2
20
MBR
VMNAME2
0
100
MBR
VMNAME2
1
20
GPT
关于如何执行此操作的任何想法?我是 Powershell 的新手,所以我不知道该怎么做。
由于 ScriptOutput 的输出是字符串,您必须自己解析它。相反,我建议将其转换为适合作为文本传递的格式,例如 CSV。
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
$report = foreach ($VM in $VMs){
$vmName = $VM.name
$output = Invoke-VMScript -ScriptText @'
Get-Disk |
select @{ l="ComputerName"; e={ $env:COMPUTERNAME } },
Number,
@{ name='Size'; expr={[int]($_.Size/1GB)} },
PartitionStyle | ConvertTo-Csv
'@ -VM $vmName -GuestUser $Username -GuestPassword $Password
$output.ScriptOutput | ConvertFrom-Csv
}
$report | FT -AutoSize
此外,正如 Theo 评论的那样,+=
可能非常昂贵,而且几乎总是不必要的。如此处所示,您可以简单地将 foreach 的输出直接收集到变量中。
编辑
由于任何额外的输出(例如错误)都与您想要的数据一起被捕获,因此可能会导致您提到的额外空白行。我能够克服这个问题的一种方法是检查列 header 是否存在,然后去除之前的任何垃圾。
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
$report = foreach ($VM in $VMs){
$output = Invoke-VMScript -ScriptText @'
Get-Disk | Foreach-Object{
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
Number = $_.number
Size = [int]($_.size/1GB)
PartitionStyle = $_.PartitionStyle
}
} | ConvertTo-Csv -NoTypeInformation
'@ -VM $vm.Name -GuestUser $Username -GuestPassword $Password
if($output.ScriptOutput -match 'PartitionStyle')
{
$output.ScriptOutput -replace '(?s)^.+(?="Com)' | ConvertFrom-Csv
}
}
$report | FT -AutoSize
我正在使用 PowerCLI 编写一个脚本来审计公司虚拟环境中的磁盘分区类型。到目前为止我得到了这个代码:
$report = @()
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
foreach ($VM in $VMs){
$vmName = $VM.Name
$output = Invoke-VMScript -ScriptText @'
Get-Disk |
select @{ l="ComputerName"; e={ $env:COMPUTERNAME } },
Number,
@{ name='Size'; expr={[int]($_.Size/1GB)} },
PartitionStyle
'@ -VM $vmName -GuestUser $Username -GuestPassword $Password
$output.ScriptOutput #printing each for testing
$report += $output.ScriptOutput
}
$report | FT -AutoSize
这将产生如下所示的输出:
ComputerName | Number | Size | PartitionStyle |
---|---|---|---|
VMNAME1 | 0 | 100 | MBR |
VMNAME1 | 1 | 20 | GPT |
VMNAME1 | 2 | 20 | MBR |
ComputerName | Number | Size | PartitionStyle |
---|---|---|---|
VMNAME2 | 0 | 100 | MBR |
VMNAME2 | 1 | 20 | GPT |
我面临的问题是输出报告中每个虚拟机都重复了 headers 列。我怎样才能解决这个问题,只显示一次 headers 列,如下所示:
ComputerName | Number | Size | PartitionStyle |
---|---|---|---|
VMNAME1 | 0 | 100 | MBR |
VMNAME1 | 1 | 20 | GPT |
VMNAME1 | 2 | 20 | MBR |
VMNAME2 | 0 | 100 | MBR |
VMNAME2 | 1 | 20 | GPT |
关于如何执行此操作的任何想法?我是 Powershell 的新手,所以我不知道该怎么做。
由于 ScriptOutput 的输出是字符串,您必须自己解析它。相反,我建议将其转换为适合作为文本传递的格式,例如 CSV。
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
$report = foreach ($VM in $VMs){
$vmName = $VM.name
$output = Invoke-VMScript -ScriptText @'
Get-Disk |
select @{ l="ComputerName"; e={ $env:COMPUTERNAME } },
Number,
@{ name='Size'; expr={[int]($_.Size/1GB)} },
PartitionStyle | ConvertTo-Csv
'@ -VM $vmName -GuestUser $Username -GuestPassword $Password
$output.ScriptOutput | ConvertFrom-Csv
}
$report | FT -AutoSize
此外,正如 Theo 评论的那样,+=
可能非常昂贵,而且几乎总是不必要的。如此处所示,您可以简单地将 foreach 的输出直接收集到变量中。
编辑
由于任何额外的输出(例如错误)都与您想要的数据一起被捕获,因此可能会导致您提到的额外空白行。我能够克服这个问题的一种方法是检查列 header 是否存在,然后去除之前的任何垃圾。
$VMs = (Get-VM).where{$_.PowerState -eq 'PoweredOn' -and $_.Guest.OSFullName -match 'Windows'}
$report = foreach ($VM in $VMs){
$output = Invoke-VMScript -ScriptText @'
Get-Disk | Foreach-Object{
[PSCustomObject]@{
ComputerName = $env:COMPUTERNAME
Number = $_.number
Size = [int]($_.size/1GB)
PartitionStyle = $_.PartitionStyle
}
} | ConvertTo-Csv -NoTypeInformation
'@ -VM $vm.Name -GuestUser $Username -GuestPassword $Password
if($output.ScriptOutput -match 'PartitionStyle')
{
$output.ScriptOutput -replace '(?s)^.+(?="Com)' | ConvertFrom-Csv
}
}
$report | FT -AutoSize