2017-08-29 10 views
0

以下のpowershellスクリプトを使用してリスト内のサーバーをループし、サーバーのホスト名に応じて特定のタスクを実行しました。以下のスクリプトでは、$ server = 'server1'の場合、他のサーバーとは違って別のタスクを実行したいのですが、このループは 'else'ループを直接実行しています。私はここに何かを逃していますか? $Serverが呼び出しコマンドのスクリプトブロックの内部にあるのでpowershell for-eachループのロジック

$servernames = @("server1", "server2", "server3") 
$user = '**********' 
$Password = '*******' 
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force 
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $SecurePassword 

foreach($server in $servernames) 
{ 
    Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {   
     if ($server -eq 'server1') 
     { 
      #do some task on server1 
     } 
     else 
     { 
      #do tasks for remaining servers 
     } 
    } 

    if ($error) { exit 1 } 
} 

答えて

0

$server変数の値は、リモートシステムに渡されるとスコープ外になります。そのことを防ぐために、必要なパラメータを渡す必要があります。これを行うには、あなたはその後、Invoke-CommandArgumentListパラメータを使用する関数として使用して、それのためのパラメータを定義し、スクリプトブロックに値を渡すために扱う:

foreach ($server in $servernames) { 
    Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {   
     Param($server) 
     if ($server -eq 'server1') { 
      #do some task on server1 
     } 
     else { 
      #do tasks for remaining servers 
     } 
    } -ArgumentList $server 

    if ($error) { exit 1 } 
} 

は何が起こっているのかについて、もう少し明確にするために、スクリプトブロックが使用するパラメータの名前を変更します。

foreach ($server in $servernames) { 
    Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {   
     Param($MyServer) 
     if ($MyServer -eq 'server1') { 
      #do some task on server1 
     } 
     else { 
      #do tasks for remaining servers 
     } 
    } -ArgumentList $Server 

    if ($error) { exit 1 } 
} 
+0

ありがとうございます。それに加えて、私は、invoke-commandを使ってリスト内のすべてのサーバ上で実行する必要のあるunzip関数を持っていました。各サーバのinvoke-commandループ内でunzip関数を宣言するのではなく、より良い方法がありますか? 追加型-AssemblyName System.IO.Compression.FileSystemを 機能解凍 {PARAM([文字列] $ zipファイル、[文字列]の$ OUTPATH) [System.IO.Compression.ZipFile] :: ExtractToDirectory($ zipfile、$ outpath) } – workholic

+0

@workholicいいえ、何とかリモートセッションで関数を宣言する必要があります。リモートセッションは、ローカルセッションとはまったく異なります。それに渡す唯一のものは、明示的に渡すものです。 –

1

、そのスコープに存在しません。 -Argumentlistまたは "使用"スコープ(PS3 +)で渡すことができます。 if ($using:server -eq 'server1')しかしifの文をInvoke-Commandの外側に置くと、より意味があります。

if ($server -eq 'server1') { 
    Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock { 
     "Stuff to do on Server1" 
    } 
} else { "Other Servers"} 
1

あなたのスクリプトブロックは異なる範囲にあり、$serverは表示されません。私はコマンドを実行する前にあなたのロジックを理解することをお勧めします。

If ($Server -eq 'server1') 
{ Invoke-Command -ComputerName $Server -Credential $Cred -ScriptBlock {} } 
関連する問題