是否可以在工作流中调用命令?
Is it possible to invoke-command with in a workflow?
有人知道我是否可以在 PowerShell 工作流程中使用 Invoke-Command
吗?
目前我有脚本循环遍历包含服务列表的文本文件,但我希望它一次推送到所有服务器,而不是逐一推送。这可能吗?
这是我正在使用的当前脚本块:
{
ForEach ($Server in $Servers) {
Write-Host "Copying code to $Server..."
If (!(Test-Path -path \$Server\c$\Websites\Versions\v$version)) {
New-Item \$Server\c$\Websites\Versions\v$version -Type Directory | Out-Null
}
Copy-Item .\Packages\v$version\* \$Server\c$\Websites\Versions\v$version -Force -Recurse
Write-Host "Converting to application on $Server..."
Invoke-Command -ComputerName $Server -ScriptBlock $Script -Argumentlist $Version | Out-Null
}
}
PowerShell 工作流引擎无法直接调用 PowerShell cmdlet。相反,如果脚本编写者在工作流定义内调用 PowerShell cmdlet,PowerShell 工作流引擎将自动将 PowerShell cmdlet 的调用包装在 InlineScript
工作流 Activity.
内
workflow test
{
ForEach ($Server in $Servers) {
Write-Host "Copying code to $Server..."
If (!(Test-Path -path \$Server\c$\Websites\Versions\v$version)) {
New-Item \$Server\c$\Websites\Versions\v$version -Type Directory | Out-Null
}
Copy-Item .\Packages\v$version\* \$Server\c$\Websites\Versions\v$version -Force -Recurse
Write-Host "Converting to application on $Server..."
InlineScript {
Invoke-Command -ComputerName $Server -ScriptBlock $Script -Argumentlist $Version | Out-Null
}
}
}
至于能不能用,就按照Mathias的建议去试一下吧
@Trevor 的 作为一个整体骨架很好,但它不会像现在这样工作。
有几项缺失或不正确:
- 向工作流传递参数
- 向 InlineScript 传递参数
- 将 ScriptBlock 作为参数传递;
- 在工作流中使用 Out-Null
工作示例:
$serversProd=@"
server1
server2
server3
server4
"@-split'\r\n'
$reportScript = "report.script.ps1"
$generateReport = {
param($reportScript)
cd D:\Automations\ConnectivityCheck
powershell -file $reportScript
}
workflow check-connectivity {
Param ($servers, $actionBlock, $reportScript)
# Prepare the results folder
$resultsFolder = "D:\Automations\ConnectivityCheckResults"
$unused1 = mkdir -Force $resultsFolder
# Run on all servers in parallel
foreach -parallel ($server in $servers) {
# Upload script to the server
$unused2 = mkdir -Force \$server\D$\Automations\ConnectivityCheck
cp -Force $reportScript \$server\D$\Automations\ConnectivityCheck\
"Starting on $server..."
# Execute script on the server. It should contain Start-Transcript and Stop-Transcript commands
# For example:
# $hostname = $(Get-Wmiobject -Class Win32_ComputerSystem).Name
# $date = (Get-Date).ToString("yyyyMMdd")
# Start-Transcript -path ".$date.$hostname.connectivity.report.txt"
# ...Code...
# Stop-Transcript
$results = InlineScript {
$scriptBlock = [scriptblock]::Create($Using:actionBlock)
Invoke-Command -computername $Using:server -ScriptBlock $scriptBlock -ArgumentList $Using:reportScript
}
# Download transcript file from the server
$transcript = [regex]::Match($results,"Transcript started.+?file is \.\([^\s]+)").groups[1].value
"Completed on $server. Transcript file: $transcript"
cp -Force \$server\D$\Automations\ConnectivityCheck$transcript $resultsFolder\
}
}
cls
# Execute workflow
check-connectivity $serversProd $generateReport $reportScript
有人知道我是否可以在 PowerShell 工作流程中使用 Invoke-Command
吗?
目前我有脚本循环遍历包含服务列表的文本文件,但我希望它一次推送到所有服务器,而不是逐一推送。这可能吗?
这是我正在使用的当前脚本块:
{
ForEach ($Server in $Servers) {
Write-Host "Copying code to $Server..."
If (!(Test-Path -path \$Server\c$\Websites\Versions\v$version)) {
New-Item \$Server\c$\Websites\Versions\v$version -Type Directory | Out-Null
}
Copy-Item .\Packages\v$version\* \$Server\c$\Websites\Versions\v$version -Force -Recurse
Write-Host "Converting to application on $Server..."
Invoke-Command -ComputerName $Server -ScriptBlock $Script -Argumentlist $Version | Out-Null
}
}
PowerShell 工作流引擎无法直接调用 PowerShell cmdlet。相反,如果脚本编写者在工作流定义内调用 PowerShell cmdlet,PowerShell 工作流引擎将自动将 PowerShell cmdlet 的调用包装在 InlineScript
工作流 Activity.
workflow test
{
ForEach ($Server in $Servers) {
Write-Host "Copying code to $Server..."
If (!(Test-Path -path \$Server\c$\Websites\Versions\v$version)) {
New-Item \$Server\c$\Websites\Versions\v$version -Type Directory | Out-Null
}
Copy-Item .\Packages\v$version\* \$Server\c$\Websites\Versions\v$version -Force -Recurse
Write-Host "Converting to application on $Server..."
InlineScript {
Invoke-Command -ComputerName $Server -ScriptBlock $Script -Argumentlist $Version | Out-Null
}
}
}
至于能不能用,就按照Mathias的建议去试一下吧
@Trevor 的
- 向工作流传递参数
- 向 InlineScript 传递参数
- 将 ScriptBlock 作为参数传递;
- 在工作流中使用 Out-Null
工作示例:
$serversProd=@"
server1
server2
server3
server4
"@-split'\r\n'
$reportScript = "report.script.ps1"
$generateReport = {
param($reportScript)
cd D:\Automations\ConnectivityCheck
powershell -file $reportScript
}
workflow check-connectivity {
Param ($servers, $actionBlock, $reportScript)
# Prepare the results folder
$resultsFolder = "D:\Automations\ConnectivityCheckResults"
$unused1 = mkdir -Force $resultsFolder
# Run on all servers in parallel
foreach -parallel ($server in $servers) {
# Upload script to the server
$unused2 = mkdir -Force \$server\D$\Automations\ConnectivityCheck
cp -Force $reportScript \$server\D$\Automations\ConnectivityCheck\
"Starting on $server..."
# Execute script on the server. It should contain Start-Transcript and Stop-Transcript commands
# For example:
# $hostname = $(Get-Wmiobject -Class Win32_ComputerSystem).Name
# $date = (Get-Date).ToString("yyyyMMdd")
# Start-Transcript -path ".$date.$hostname.connectivity.report.txt"
# ...Code...
# Stop-Transcript
$results = InlineScript {
$scriptBlock = [scriptblock]::Create($Using:actionBlock)
Invoke-Command -computername $Using:server -ScriptBlock $scriptBlock -ArgumentList $Using:reportScript
}
# Download transcript file from the server
$transcript = [regex]::Match($results,"Transcript started.+?file is \.\([^\s]+)").groups[1].value
"Completed on $server. Transcript file: $transcript"
cp -Force \$server\D$\Automations\ConnectivityCheck$transcript $resultsFolder\
}
}
cls
# Execute workflow
check-connectivity $serversProd $generateReport $reportScript