我有一个奇怪的行为与格式列表。 当我将下面的代码直接粘贴到shell中时,所有的东西都像一个魅力一样:
@("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; $u = gwmi win32_useraccount |? { $_.Name –eq $uname } if (-not $u) { write-host ("[-] "+ $uname + " does not exist!") } else { write-host ("[+] "+ $uname + ":") $u } } @("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; gwmi win32_groupuser -computer . | select GroupComponent,PartComponent |? { $_.PartComponent -match ",Name=`""+$uname+"`""} | fl * }
但是,当我把相同的代码放在一个函数中,比如说testing,然后调用testing,PowerShell就会抛出一个关于格式列表的错误。 我不明白为什么 – 也许我一直在寻找错误的结局,但是我什么也没find。
function test { @("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; $u = gwmi win32_useraccount |? { $_.Name –eq $uname } if (-not $u) { write-host ("[-] "+ $uname + " does not exist!") } else { write-host ("[+] "+ $uname + ":") $u } } @("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; gwmi win32_groupuser -computer . | select GroupComponent,PartComponent |? { $_.PartComponent -match ",Name=`""+$uname+"`""} | fl * } }
显示的错误信息是:
out-lineoutput:“Microsoft.PowerShell.Commands.Internal.Format.FormatStartData”types的对象无效或不正确的顺序。 这可能是由于
与默认格式相冲突的用户指定的“格式列表”命令。
+ CategoryInfo:InvalidData:(:) [out-lineoutput],InvalidOperationException
+ FullyQualifiedErrorId:ConsoleLineOutputOutOfSequencePacket,Microsoft.PowerShell.Commands.OutLineOutputCommand
问题的屏幕截图:

一个函数应该返回一个或多个对象,而不是格式化的输出数据(用于主机/屏幕)。
换句话说, 不要在函数中使用Format- * cmdlet
只需从最后一条语句中删除|fl * ,然后将test函数调用的输出传递给Format-List :
function test { @("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; $u = gwmi win32_useraccount |? { $_.Name –eq $uname } if (-not $u) { write-host ("[-] "+ $uname + " does not exist!") } else { write-host ("[+] "+ $uname + ":") $u } } @("Administrator","SomeUser","SomeOtherUser") |% { $uname = $_; gwmi win32_groupuser -computer . | select GroupComponent,PartComponent |? { $_.PartComponent -match ",Name=`""+$uname+"`""} } } test |fl *
沿着同样的路线,至less为了编写可重用的function:
% , select , gwmi ) 您可能也会从Get-WmiObject使用-Query参数,并使WMI执行过滤,而不是将所有用户返回给PowerShell, 然后对其进行过滤
Get-WmiObject -Query "SELECT * FROM Win32_UserAccount WHERE Name = '$uname'"