我正在处理一个脚本,该脚本可以远程转换为一系列服务器并执行来自一系列PoSh功能的命令。我需要保留同步处理,并且只想添加在函数上执行异步操作的功能。
如何使用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
}
答案 0 :(得分:1)
Import-Module .\down.psm1
可能会失败,因为Start-Job
没有与您的脚本相同的工作目录,因此您需要更改工作目录或使用模块的绝对路径。$scriptblock
中的Start-Job
是什么?它从未创造过。请注意,$scriptblock
需要使用$args[0] , $args[1] ..
来访问使用-ArgumentList
传递的值,或者在scriptblock的开头定义参数(param($server,$filepath...)
)。您可以尝试这样的事情:
#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'
我使用([scriptblock]::Create("Import-Module $module"))
生成InitializationScript以确保$module
- 变量已扩展为文件路径,因为$module
在新作业线程中不可用。如果要对模块路径进行硬编码,可以将其替换为-InitializationScript { Import-Module c:\mymodule\down.psm1 }
。