qfarm /load
命令显示我的服务器的负载。
输出:
PS> qfarm /load
Server Name Server Load Load Throttling Load Logon Mode
-------------------- ----------- -------------------- ------------------
SERVER-01 400 0 AllowLogons
SERVER-02 1364 OFF AllowLogons
SERVER-03 1364 OFF AllowLogons
SERVER-04 1000 0 AllowLogons
SERVER-05 700 0 AllowLogons
SERVER-06 1200 0 AllowLogons
我只需要显示第一列(服务器名称)和第二列(服务器负载)并循环它们,以便稍后进行一些逻辑,但似乎powershell没有将其视为具有属性的对象:
PS> qfarm /load | Select -ExpandProperty "Server Name"
Select-Object : Property "Server Name" cannot be found.
还有其他可能性吗,比如桌子之类的?
实现此目的的一种方法是从命令的输出中构建对象。测试了以下内容:
#requires -version 3
# sample data output from command
$sampleData = @"
Server Name Server Load Load Throttling Load Logon Mode
-------------------- ----------- -------------------- ------------------
SERVER-01 400 0 AllowLogons
SERVER-02 1364 OFF AllowLogons
SERVER-03 1364 OFF AllowLogons
SERVER-04 1000 0 AllowLogons
SERVER-05 700 0 AllowLogons
SERVER-06 1200 0 AllowLogons
"@ -split "`n"
$sampleData | Select-Object -Skip 2 | ForEach-Object {
$len = $_.Length
[PSCustomObject] @{
"ServerName" = $_.Substring(0, 22).Trim()
"ServerLoad" = $_.Substring(22, 13).Trim() -as [Int]
"LoadThrottlingLoad" = $_.Substring(35, 22).Trim()
"LogonMode" = $_.Substring(57, $len - 57).Trim()
}
}
在您的情况下,您应该能够将
$sampleData
替换为 qfarm load
命令;例如:
qfarm /load | Select-Object -Skip 2 | ForEach-Object {
...
当然,这是假设输出中没有空行,并且我的每个项目开头的列位置是正确的。
PowerShell 版本 2 等效项:
#requires -version 2
function Out-Object {
param(
[Collections.Hashtable[]] $hashData
)
$order = @()
$result = @{}
$hashData | ForEach-Object {
$order += ($_.Keys -as [Array])[0]
$result += $_
}
New-Object PSObject -Property $result | Select-Object $order
}
# sample data output from command
$sampleData = @"
Server Name Server Load Load Throttling Load Logon Mode
-------------------- ----------- -------------------- ------------------
SERVER-01 400 0 AllowLogons
SERVER-02 1364 OFF AllowLogons
SERVER-03 1364 OFF AllowLogons
SERVER-04 1000 0 AllowLogons
SERVER-05 700 0 AllowLogons
SERVER-06 1200 0 AllowLogons
"@ -split "`n"
$sampleData | Select-Object -Skip 2 | ForEach-Object {
$len = $_.Length
Out-Object `
@{"ServerName" = $_.Substring(0, 22).Trim()},
@{"ServerLoad" = $_.Substring(22, 13).Trim() -as [Int]},
@{"LoadThrottlingLoad" = $_.Substring(35, 22).Trim()},
@{"LogonMode" = $_.Substring(57, $len - 57).Trim()}
}
您可以使用 PowerShell Gallery
中的
ConvertFrom-SourceTable
cmdlet 轻松将表转换为 PowerShell 对象:
Install-Script -Name ConvertFrom-SourceTable
$sampleData = ConvertFrom-SourceTable @"
Server Name Server Load Load Throttling Load Logon Mode
-------------------- ----------- -------------------- ------------------
SERVER-01 400 0 AllowLogons
SERVER-02 1364 OFF AllowLogons
SERVER-03 1364 OFF AllowLogons
SERVER-04 1000 0 AllowLogons
SERVER-05 700 0 AllowLogons
SERVER-06 1200 0 AllowLogons
"@
然后选择您的列,例如:
PS C:\> $SampleData | Select-Object "Server Name", "Server Load"
Server Name Server Load
----------- -----------
SERVER-01 400
SERVER-02 1364
SERVER-03 1364
SERVER-04 1000
SERVER-05 700
SERVER-06 1200
详情请参阅:
ConvertFrom-SourceTable -?
ConvertFrom-SourceTable
cmdlet 可以在 PowerShell Gallery 下载,源代码可以从 GitHub iRon7/ConvertFrom-SourceTable
存储库下载。
命令行实用程序将其输出作为字符串数组返回。这应该有效:
qfarm /load | ForEach-Object { $_.Substring(0,33) }
我过去回答过与此非常相似的问题。我有一个更大的函数,但简化了左对齐字符串表的工作,正如您在示例中所示的那样。请参阅链接的答案以获取更多说明。
function ConvertFrom-LeftAlignedStringData{
param (
[string[]]$data
)
$headerString = $data[0]
$headerElements = $headerString -split "\s{2,}" | Where-Object{$_}
$headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}
$results = $data | Select-Object -Skip 2 | ForEach-Object{
$props = @{}
$line = $_
For($indexStep = 0; $indexStep -le $headerIndexes.Count - 1; $indexStep++){
$value = $null # Assume a null value
$valueLength = $headerIndexes[$indexStep + 1] - $headerIndexes[$indexStep]
$valueStart = $headerIndexes[$indexStep]
If(($valueLength -gt 0) -and (($valueStart + $valueLength) -lt $line.Length)){
$value = ($line.Substring($valueStart,$valueLength)).Trim()
} ElseIf ($valueStart -lt $line.Length){
$value = ($line.Substring($valueStart)).Trim()
}
$props.($headerElements[$indexStep]) = $value
}
New-Object -TypeName PsCustomObject -Property $props
}
return $results
}
$qfarmOutput = qfarm /load
ConvertFrom-LeftAlignedStringData $qfarmOutput | select "Server Name","Server Load"
此方法基于标头字段的位置。没有什么是硬编码的,它都是基于这些索引和字段名称自定义构建的。使用这些
$headerIndexes
,我们分割每一行并将结果(如果存在)放入相应的列中。有逻辑确保我们不会尝试抓取字符串中可能不存在的任何部分,并将最后一个字段特殊对待。
Server Name Server Load
----------- -----------
SERVER-01 400
SERVER-02 1364
SERVER-03 1364
SERVER-04 1000
SERVER-05 700
SERVER-06 1200