在这个PowerShell脚本中奇怪的格式列表行为

我有一个奇怪的行为与格式列表。 当我将下面的代码直接粘贴到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:

  • 不要在你的函数中使用写主机 – 这是不好的
  • 使用完整的cmdlet名称而不是别名(如%selectgwmi

您可能也会从Get-WmiObject使用-Query参数,并使WMI执行过滤,而不是将所有用户返回给PowerShell, 然后对其进行过滤

 Get-WmiObject -Query "SELECT * FROM Win32_UserAccount WHERE Name = '$uname'"