简体   繁体   English

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

[英]How to pass output from a PowerShell cmdlet to a script?

I'm attempting to run a PowerShell script with the input being the results of another PowerShell cmdlet. 我正在尝试运行PowerShell脚本,输入内容是另一个PowerShell cmdlet的结果。 Here's the cross-forest Exchange 2013 PowerShell command I can run successfully for one user by specifying the -Identity parameter: 这是跨林的Exchange 2013 PowerShell命令,通过指定-Identity参数,我可以为一个用户成功运行:

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

I want to run this command for all MailUsers. 我想为所有MailUsers运行此命令。 Therefore, what I want to run is: 因此,我要运行的是:

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

Note that I removed the -Identity parameter because I was feeding it from each Get-MailUser 's WindowsEmailAddress property value. 请注意,我删除了-Identity参数,因为我是从每个Get-MailUserWindowsEmailAddress属性值提供它的。 However, this returns with a pipeline input error. 但是,这会返回并带有管道输入错误。

I also tried exporting the WindowsEmailAddress property values to a CSV, and then reading it as per the following site, but I also got a pipeline problem: http://technet.microsoft.com/en-us/library/ee861103(v=exchg.150).aspx 我还尝试将WindowsEmailAddress属性值导出为CSV,然后按照以下站点进行读取,但是我也遇到了管道问题: http : //technet.microsoft.com/zh-cn/library/ee861103(v= exchg.150).aspx

Import-Csv mailusers.csv | Prepare-MoveRequest.ps1 -RemoteForestDomainController DC.remotedomain.com -RemoteForestCredential $Remote

What is the best way to feed the windowsemailaddress field from each MailUser to my Prepare-MoveRequest.ps1 script? 将每个MailUser的windowsemailaddress字段馈送到我的Prepare-MoveRequest.ps1脚本的最佳方法是什么?

EDIT : I may have just figured it out with the following foreach addition to my Import-Csv option above. 编辑 :我可能刚刚在我的Import-Csv选项中添加了以下foreach Import-Csv I'm testing it now: 我正在测试它:

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

You should declare your custom function called Prepare-MoveRequest instead of simply making it a script. 您应该声明一个名为Prepare-MoveRequest自定义函数,而不是简单地使其成为脚本。 Then, dot-source the script that declares the function, and then call the function. 然后,点源声明该函数的脚本,然后调用该函数。 To accept pipeline input into your function, you need to declare one or more parameters that use the appropriate parameter attributes, such as ValueFromPipeline or ValueFromPipelineByPropertyName . 要将管道输入接受到函数中,您需要声明一个或多个使用适当参数属性的参数,例如ValueFromPipelineValueFromPipelineByPropertyName Here is the official MSDN documentation for parameter attributes. 这是参数属性的官方MSDN文档

For example, let's say I was developing a custom Stop-Process cmdlet. 例如,假设我在开发自定义Stop-Process cmdlet。 I want to stop a process based on the ProcessID (or PID ) of a Windows process. 我想基于Windows进程的ProcessID (或PID )停止一个进程。 Here is what the command would look like: 该命令如下所示:

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;

Now that we've taken a look at an example of building the custom function ... once you've defined your custom function in your script file, dot-source it in your "main" script. 现在,我们看了构建自定义函数的示例...在脚本文件中定义了自定义函数后,请在“主”脚本中对其进行点源化。

# 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.

EDIT : I would like to point out that your edit to your post does not properly handle parameter binding in PowerShell. 编辑 :我想指出,您对帖子的编辑不能正确处理PowerShell中的参数绑定。 It may achieve the desired results, but it does not teach the correct method of binding parameters in PowerShell. 它可能会达到期望的结果,但是它没有教导PowerShell中绑定参数的正确方法。 You don't have to use the ForEach-Object to achieve your desired results. 您不必使用ForEach-Object即可达到所需的结果。 Read through my post, and I believe you will increase your understanding of parameter binding. 通读我的文章,相信您会增加对参数绑定的了解。

我的foreach循环成功了。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM