将变量传递给脚本块PowerShell

时间:2015-03-13 15:10:53

标签: powershell powershell-v2.0 powershell-v3.0

我似乎很难理解如何使其正常工作。我试图在前面收集所有变量,我可以调用psexec并在scriptblock中将这些变量传递给它。

我使用psexec的原因是因为我有旧的2003服务器没有安装PowerShell。我的目标是让PowerShell多线程对照文本文件中的服务器列表,并以下面的方式生成进程。

    #Gather info
    $servers = "test1234"
    $userName = Read-host "What is the user name?"
    $userPassword = Read-host "What is the user password?"

    $scriptBlockwork = {c:\scripts\message\psexec.exe "$servers" -u domain\$userName -p $userPassword -c InstallMShotfix.cmd -f InstallMShotfix.cmd}.GetNewClosure()
    & $scriptBlockwork
    echo $scriptBlockwork

为什么即使使用.GetNewClosure()

,脚本块也不会采用定义的变量

3 个答案:

答案 0 :(得分:1)

从您的问题中,您想要绑定参数的顺序,但是为了正确的闭包,这一点并不完全清楚:

$PartialInstaller = {
    param($servers)
    return {
        param($userName,$userPassword)
        c:\scripts\message\psexec.exe "$servers" -u domain\$userName -p $userPassword -c InstallMShotfix.cmd -f InstallMShotfix.cmd
    }.GetNewClosure()
}

$Installer = &$PartialInstaller $servers
$Result = &Installer "username","password"

或者,呼叫运营商(&)也支持splatting

$ScriptArguments = @{}
$ScriptArguments.servers = "test1234"
$ScriptArguments.userName = Read-host "What is the user name?"
$ScriptArguments.userPassword = Read-host "What is the user password?"

$Work = {
    param($servers,$userName,$userPassword)
    c:\scripts\message\psexec.exe "$servers" -u domain\$userName -p $userPassword -c InstallMShotfix.cmd -f InstallMShotfix.cmd
}

& $Work @ScriptArguments

答案 1 :(得分:0)

不确定原因,但我从未能让.getnewclosure()为此工作。

幸运的是[scriptblock]::Create()提供了一种解决方法:

#Gather info
    $servers = "test1234"
    $userName = Read-host "What is the user name?"
    $userPassword = Read-host "What is the user password?"

    $scriptBlockwork = 
    [scriptblock]::Create(@"
    c:\scripts\message\psexec.exe "$servers" -u domain\$userName -p $userPassword -c InstallMShotfix.cmd -f InstallMShotfix.cmd
"@)
    & $scriptBlockwork
    echo $scriptBlockwork

答案 2 :(得分:0)

TechNet上的

invoke-command

示例2和示例5均与您的示例类似。

示例3和示例4允许您在没有psexec的情况下执行此操作,但您需要在远程计算机上启用WinRM。如果您需要执行许多命令,这些特别有用。

同时研究Get-Credential以提示身份验证。根据环境(组织中的信息安全策略等),您可以将凭据存储在文件(加密格式)中,并在脚本中重复使用。最低限度,您将不会通过明确的电汇传递管理员凭据。

TL; DR Invoke-Command是你的朋友。 Get-Credential比Read-Host更安全。

$Credential = $get-credential
foreach ($Server in $Serverlist) {
    $scriptBlockwork = { psexec $Server -c InstallMShotfix.cmd -f InstallMShotfix.cmd }
    Invoke-Command -credential $Credential -scriptblock $scriptBlockwork
}

这将使用您输入的凭据运行您的psexec命令。他们需要在本地运行psexec并在远程计算机上运行cmd文件的权限。通过读入文本文件或静态定义它来填充$ Serverlist。