我的 format-list 行为有些奇怪。当我将以下代码直接粘贴到 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 *
}
但是,当我将相同的代码放入函数(例如 test)并调用 test 时,PowerShell 会抛出有关 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+"`""} | fl *
}
}
显示的错误信息是:
out-lineoutput:类型为“Microsoft.PowerShell.Commands.Internal.Format.FormatStartData”的对象无效或顺序不正确。这可能是由
用户指定的“format-list”命令导致的,该命令与默认格式冲突。
+ CategoryInfo:InvalidData: (:) [out-lineoutput],InvalidOperationException
+ FullyQualifiedErrorId:ConsoleLineOutputOutOfSequencePacket,Microsoft.PowerShell.Commands.OutLineOutputCommand
问题截图:
答案1
函数应该返回一个或多个对象,而不是格式化的输出数据(用于主机/屏幕)。
换句话说,不要在函数内使用 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 *
同样的,至少对于编写可重用的函数来说:
- 不要使用在你的函数中写入 Host - 这很糟糕
- 使用完整的 cmdlet 名称,而不是别名(例如
%
、select
、gwmi
)
您可能还会受益于使用-Query
参数Get-WmiObject
,并让 WMI 进行过滤,而不是将所有用户返回到 powershell 和然后过滤它们
Get-WmiObject -Query "SELECT * FROM Win32_UserAccount WHERE Name = '$uname'"