如何将PowerShell cmdlet的输出传递给脚本?

时间:2013-12-28 22:21:27

标签: powershell

我正在尝试运行PowerShell脚本,其输入是另一个PowerShell cmdlet的结果。这是我可以通过指定-Identity参数为一个用户成功运行的跨林Exchange 2013 PowerShell命令:

.\Prepare-MoveRequest.ps1 -Identity "user@domain.com" -RemoteForestDomainController "dc.remotedomain.com" $Remote -UseLocalObject -OverwriteLocalObject -Verbose

我想为所有MailUser运行此命令。因此,我想要运行的是:

Get-MailUser | select windowsemailaddress | .\Prepare-MoveRequest.ps1 -RemoteForestDomainController "dc.remotedomain.com" $Remote -LocalForestDomainController "dc.localdomain.com" -UseLocalObject -OverwriteLocalObject -Verbose

请注意,我删除了-Identity参数,因为我是从每个Get-MailUser的{​​{1}}属性值中提取的。但是,这会返回管道输入错误。

我还尝试将WindowsEmailAddress属性值导出为CSV,然后按照以下网站读取它,但我也遇到了管道问题:http://technet.microsoft.com/en-us/library/ee861103(v=exchg.150).aspx

WindowsEmailAddress

将每个MailUser的windowsemailaddress字段提供给Prepare-MoveRequest.ps1脚本的最佳方法是什么?

编辑:我可能刚刚通过上面的Import-Csv mailusers.csv | Prepare-MoveRequest.ps1 -RemoteForestDomainController DC.remotedomain.com -RemoteForestCredential $Remote 选项添加了以下foreach来解决这个问题。我现在正在测试它:

Import-Csv

2 个答案:

答案 0 :(得分:0)

您应该声明名为Prepare-MoveRequest的自定义函数,而不是简单地将其设为脚本。然后,点源声明该函数的脚本,然后调用该函数。要接受管道输入到函数中,您需要声明一个或多个使用适当参数属性的参数,例如ValueFromPipelineValueFromPipelineByPropertyName。以下是参数属性的official MSDN documentation

例如,假设我正在开发一个自定义Stop-Process cmdlet。我想根据Windows进程的ProcessID(或PID)停止进程。这是命令的样子:

function Stop-CustomProcess {
    # Specify the CmdletBinding() attribute for our
    # custom advanced function.
    [CmdletBinding()]
    # Specify the PARAM block, and declare the parameter
    # that accepts pipeline input
    param (
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int] $Id
    )

    # You must specify the PROCESS block, because we want this
    # code to execute FOR EACH process that is piped into the
    # cmdlet. If we do not specify the PROCESS block, then the
    # END block is used by default, which only would run once.
    process {
        Write-Verbose -Message ('Stopping process with PID: {0}' -f $ID);
        # Stop the process here
    }
}

# 1. Launch three (3) instances of notepad
1..3 | % { notepad; };

# 2. Call the Stop-CustomProcess cmdlet, using pipeline input
Get-Process notepad | Stop-CustomProcess -Verbose;

# 3. Do an actual clean-up
Get-Process notepad | Stop-Process;

现在我们已经看了一个构建自定义函数的示例...一旦在脚本文件中定义了自定义函数,就在“主”脚本中点源它。

# Import the custom function into the current session
. $PSScriptRoot\Prepare-MoveRequest.ps1
# Call the function
Get-MailUser | Prepare-MoveRequest -RemoteForestDomainController dc.remotedomain.com $Remote -LocalForestDomainController dc.localdomain.com -UseLocalObject -OverwriteLocalObject -Verbose;
# Note: Since you've defined a parameter named `-WindowsEmailAddress` that uses the `ValueFromPipelineByPropertyName` attribute, the value of each object will be bound to the parameter, as it passes through the `PROCESS` block.

编辑:我想指出,您对帖子的编辑无法正确处理PowerShell中的参数绑定。它可能会达到预期的效果,但它没有教会在PowerShell中绑定参数的正确方法。您不必使用ForEach-Object来获得所需的结果。仔细阅读我的帖子,我相信你会增加对参数绑定的理解。

答案 1 :(得分:0)

我的foreach循环完成了这个伎俩。

Import-Csv mailusers.csv | foreach { Prepare-MoveRequest.ps1 -Identity $_.windowsemailaddress -RemoteForestDomainController DC.remotedomain.com -RemoteForestCredential $Remote }