2016-04-23 12 views
0

私は、一連のサーバにリモート操作し、一連のPoSh関数からコマンドを実行するスクリプトを扱っています。私は同期処理を保持する必要があり、単純にその関数に対して非同期操作を実行する機能を追加したいと考えています。Invoke-Command/Start-JobとPSRemotingを使って作業する

Start-JobまたはInvoke-Command -AsJobを使用して、これを主機能からジョブとして呼び出すにはどうすれば変換できますか?これらの機能は、違いがある場合、PowerShellモジュールの一部です。

ここで見たさまざまな例をいくつか試しましたが、実際にはその機能を処理していないようです。

は、例えば、以下の機能のために、私が試してみた:

foreach($s in $servers) 
{ 
      if($lbFileLocation -eq $true) 
      { 
       #Rename-LoadBalancerFile -ServerName $server -Revert $false -filePath $filePath -cred $cred - #sync function works great 
       Start-Job -Name 'RenLb' -InitializationScript {Import-Module '.\Down.psm1'} $ScriptBlock -ArgumentList $server,$false,$lbFileLocation,$Cred | Out-Null 
      } 
} 

     Write-Host 'Waiting for LB rename.' 
     While (Get-Job -Name 'RenLb' | where { $_.State -eq 'Running' }) 
       { 
        Start-Sleep 1 
       } 

      Write-Host 'completed' 

オリジナル、同期機能:

function Rename-LoadBalancerFile 
{ 
    param 
    (
     [string] 
     [Parameter(Mandatory=$true)] 
     $ServerName, 
     [bool] 
     [Parameter(Mandatory=$true)] 
     $Revert, 
     [string] 
     [Parameter(Mandatory=$true)] 
     $filePath, 
     [PSCredential] 
     [Parameter(Mandatory=$false)] 
     $cred 
    ) 

    $scriptBlock = { 
     param 
     (
      [bool] 
      [Parameter(Mandatory=$true)] 
      $Revert, 
      [string] 
      [Parameter(Mandatory=$true)] 
      $filePath 
     ) 

     if(Test-Path $filePath -eq $true) 
     { 
      Write-Host 'file tested true' 
      if($Revert -eq $true) 
      { 
       $fileName = [IO.Path]::GetFileName($filePath) 
       $directory = [IO.Path]::GetDirectoryName($filePath) 

       Rename-Item -Path "$directory\file.txt" -NewName $fileName 
      } 
      else 
      { 
       Rename-Item -Path $filePath -NewName 'file.txt' 
      } 
     } 
    } 

    $session = New-PSSession -ComputerName $ServerName -Authentication Credssp -Credential $cred 
    Invoke-Command -Session $session -ScriptBlock $scriptBlock -ArgumentList $Revert, $filePath 
    Remove-PSSession $session 
} 
+1

atmをテストできません。しかし、私は 'new-session'、' invoke-command'、 'remove-session'を' Invoke-Command-ScriptBlock {} -ArgumentList $ Revert、$ filePath -ComputerName $ ServerName -Authentication Credsspで置き換えることができるはずです。資格$ cred' –

+0

関数内では?自動的にセッションを開いたり閉じたりすると、うまくいくはずです。しかし、実際に私が経験している問題を解決するだろうか? –

+0

問題は解決しません。だからそれはコメントです。 :-)ちょうどチップ –

答えて

1
Start-Jobが同じを持っていないため
  1. Import-Module .\down.psm1はおそらく失敗しますあなたのスクリプトとして作業ディレクトリを作成するので、作業ディレクトリを変更するか、モジュールへの絶対パスを使用する必要があります。
  2. $scriptblockとはStart-Jobですか?それは決して創造されません。 $scriptblockは、-ArgumentListを使用して渡された値にアクセスするか、スクリプトブロックの先頭にパラメータ(param($server,$filepath...))を定義するために$args[0] , $args[1] ..を使用する必要があります。

あなたはこのような何かを試みることができる:私は-variable $module$moduleので、ファイルパスに展開されたことを確認するInitializationScriptを生成するのに([scriptblock]::Create("Import-Module $module"))を使用

#Get full path for module 
$module = Resolve-Path ".\Down.psm1" 

#Create scriptblock 
$scriptblock = { Rename-LoadBalancerFile -ServerName $args[0] -Revert $args[1] -filePath $args[2] -cred $args[3] } 

foreach($s in $servers) 
{ 
    Start-Job -Name "RenLb" -InitializationScript ([scriptblock]::Create("Import-Module $module")) -ScriptBlock $scriptblock -ArgumentList $s,$false,$lbFileLocation,$Cred | Out-Null 
} 

Write-Host 'Waiting for LB rename.' 

While (Get-Job -Name 'RenLb' | where { $_.State -eq 'Running' }) 
{ 
    Start-Sleep 1 
} 

Write-Host 'completed' 

は新しい仕事では使用できません-糸。モジュールパスをハードコードする場合は、-InitializationScript { Import-Module c:\mymodule\down.psm1 }に置き換えることができます。

+0

それは、それは動作しませんでした試みた。ジョブは作成されますが、直ちに終了します( 'Get-Job'はジョブを見つけることができないというエラーを投げます' RenLb')。そして、はい、元のスクリプトブロックを含めるのを忘れました。それには一致するパラメータが定義されていましたが、 '$ args [0] ... 'を使っても同じです。私の前提は、これが自分自身および/またはPSRemotingと呼ばれる関数内の問題であるということです。同期的に動作しますが、 'Start-Job'の内部では動作しません。 –

+0

仕事はありませんか? :あなたは$サーバが空ではないと確信していますか? –

+0

$ serversは空ではありません。私はより明確にすべきです、*ジョブを作成しますが、 'Get-Job'がそれらを受け取る前に終了します。 –