gpt4 book ai didi

powershell - 管道进入 ScriptBlock

转载 作者:行者123 更新时间:2023-12-03 08:27:13 27 4
gpt4 key购买 nike

我正在尝试找到一些在 PowerShell 中灵活更改/替换管道元素的方法:

Function Where-DirectlyReportsTo {
Param (
[Parameter(
ValueFromPipeline = $true,
HelpMessage = "The ADUser object to be tested"
)]
[Microsoft.ActiveDirectory.Management.ADUser] $ADUser,
[Parameter(
Mandatory = $true,
ValueFromPipeline = $false,
Position = 0
)]
[String] $mgrDN
)
Process {
If ($ADUser) {
If ($ADUser.Manager -eq $mgrDN) { Return $ADUser }
}
}
}

$Properties = @("Manager")
$users = Get-ADUser -Filter * -SearchBase $OU -Properties $Properties
[ScriptBlock] $sb = {Where-DirectlyReportsTo "CN=Colonel Foobar,$OU"}
$DNs = $users | $sb | %{$_.DistinguishedName}

我想返回向 Foobar 上校报告的所有用户的 DN,但它给了我错误 Expressions are only allowed as the first element of a pipeline.

这是一个微不足道的例子,但我最终希望能够将管道步骤放入一个循环中并向其传递不同的 ScriptBlocks 以获得不同的用户集,或者使用更复杂的 ScriptBlocks(例如:{ Where-IsEmployee | Where-IsInDepartment "财务"| Where-LikesIceCream}).

我意识到我可能做错了,如果有人指出正确的方向,我将不胜感激。

编辑:为了澄清,这里是我想要完成的粗略概述:

[ScriptBlock[]] $arrBlocks = @( # lots of different cases
)
ForEach ($sb In $arrBlocks) {
$DNs = $users | $sb | %{$_.DistinguishedName}
# Then do something with the DNs
}

实际上,这可能涉及哈希表而不是数组,这样我就知道如何处理每组结果。

最佳答案

语法错误很简单:

# Wrong:
$DNs = $users | $sb | %{$_.DistinguishedName}

# Correct; note the call operator in front of $sb:
$DNs = $users | &$sb | %{$_.DistinguishedName}

这仍然让您的管道问题陷入死胡同。你不需要在这里花哨;只需通过管道将 $Input 传递给下一个函数:

[ScriptBlock] $sb = {$Input | Where-DirectlyReportsTo "CN=Colonel Foobar,$OU"}

您不应该让 $sb 本身枚举输入。这是额外的开销,如果您使用 param(),会将脚本 block 提升为一个 cmdlet。你真的不需要那个。

事实上,您可以将整个事情简化为四行,甚至是很长的一行:

$properties = @("Manager")
$managers = @(
"CN=Colonel Foobar,$OU"
"CN=Sergeant Foobar,$OU"
"CN=Random Manager,$OU"
)

$users = Get-ADUser -Filter * -SearchBase $OU -Properties $properties
$DNs = $users | ?{ $managers -contains $_.Manager } | %{ $_.DistinguishedName }

我用这段代码测试过:

$OU = 'OU=test'
$users = @(
@{
Manager = "CN=Colonel Foobar,$OU";
DistinguishedName = "Show me!"
}
@{
Manager = "CN=Anon Y Mous,$OU";
DistinguishedName = "Don't show me!"
}
'rabbit'
42
$null
@{
DistinguishedName = "Don't show me, either!"
}
@{
Manager = "CN=Random Manager,$OU";
DistinguishedName = "Show me, too!"
}
)

$managers = @(
"CN=Colonel Foobar,$OU"
"CN=Sergeant Foobar,$OU"
"CN=Random Manager,$OU"
)
$DNs = $users | ?{ $managers -contains $_.Manager } | %{ $_.DistinguishedName }

$DNs | Write-Host

如果你愿意,你可以让它更冗长一点:

$properties = @("Manager")
$managers = @(
"CN=Colonel Foobar,$OU"
"CN=Sergeant Foobar,$OU"
"CN=Random Manager,$OU"
)

$filter = { $managers -eq $_.Manager }
$selector = { $_.DistinguishedName }

$users = Get-ADUser -Filter * -SearchBase $OU -Properties $properties
$DNs = $users | ?{ &$filter } | %{ &$selector }

您听起来好像希望最终拥有多个过滤器。这也很简单:

$properties = @("Manager")
$managers = @(
"CN=Colonel Foobar,$OU"
"CN=Sergeant Foobar,$OU"
"CN=Random Manager,$OU"
)

$filters = @(
{ $managers -contains $_.Manager }
{ ![string]::IsNullOrWhiteSpace($_.DistinguishedName) }
)
$selector = { $_.DistinguishedName }

$users = Get-ADUser -Filter * -SearchBase $OU -Properties $properties
$DNs = $users | ?{ $filters.Invoke() -notcontains $false } | %{ &$selector }

关于powershell - 管道进入 ScriptBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17755504/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com