我正在编写一些PowerShell,以便在单个模块中与AWS API进行通信.我编写了一个函数,Get-CloudFormation
它返回CloudFormation的状态.我写了另一个函数,Delete-CloudFormation
在启动了一个delete-CF API请求后,尝试启动一个使用my轮询CloudFormation状态的作业Get-CloudFormation
.
我打电话Export-ModuleMember
给Get-CloudFormation
(但不是Delete-CloudFormation
;这是一个私人功能). Get-CloudFormation
先前在模块文件中定义的比Delete-CloudFormation
.
我的Start-Job
电话(内部Delete-CloudFormation
)看起来像:
$job = Start-Job -Name "CloudFormationWaitForDeleteSuccess" -ScriptBlock {
$status = ""
$time = 0
while($status -ne "DELETE_COMPLETE") {
Write-Verbose ("Checking CloudFormation status")
$stack = Get-CloudFormation -accessKey $accessKey -secretKey $secretKey -stackName $stackName
$status = $stack.Status
Start-Sleep -seconds 10
$time += 10
}
Write-Host "CloudFormation delete-complete after $time seconds $stackName"
}
Run Code Online (Sandbox Code Playgroud)
当Delete-CloudFormation
运行时,我得到一个异常:
The term …
Run Code Online (Sandbox Code Playgroud) 我使用PowerShell中的.NET组件,它使用Trace.TraceWarning
,Trace.TraceInformation
等等.
我想在运行Powershell脚本时将这些跟踪输出到控制台.
当我在当前会话中使用该组件时,这可以工作.例如(模拟跟踪的效果)给控制台输出'Hello':
$listener = new-object "system.diagnostics.consoletracelistener"
[System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
[System.Diagnostics.Trace]::TraceInformation("Hello")
Run Code Online (Sandbox Code Playgroud)
但是如果我在Powershell工作中做同样的事情,我得不到任何输出,即使ConsoleTraceListener应该写入STDOUT,反过来我希望被工作捕获.(有趣的是,Console.WriteLine
这也不适合工作 - 但Write-Host
确实如此).
我这样开始工作:
$work = {
$listener = new-object "system.diagnostics.consoletracelistener"
[System.Diagnostics.Trace]::Listeners.Add($listener) | Out-Null
[System.Diagnostics.Trace]::TraceInformation("Hello")
}
$job = Start-Job -RunAs32 -ScriptBlock $work
$job | Receive-Job -Wait
Run Code Online (Sandbox Code Playgroud) 我很难理解在PowerShell中处理大型数据集/数组的最有效方法。我的阵列中有数百万个项目需要处理和分组。此列表的大小始终不同,这意味着可以是350万个或1000万个项目。
示例:将350万个项目按“ 4”分组,如下所示:
项目0、1、2、3组合在一起4,5,6,7组合在一起,依此类推。
我尝试通过遍历列表并分配给pscustomobject来使用单线程处理数组,而该工作仅需要45-50分钟即可完成。
我还尝试将数组拆分为较小的数组,但这会使进程运行更长的时间。
$i=0
$d_array = @()
$item_array # Large dataset
While ($i -lt $item_array.length){
$o = "Test"
$oo = "Test"
$n = $item_array[$i];$i++
$id = $item_array[$i];$i++
$ir = $item_array[$i];$i++
$cs = $item_array[$i];$i++
$items = [PSCustomObject]@{
'field1' = $o
'field2' = $oo
'field3' = $n
'field4' = $id
'field5' = $ir
'field6'= $cs
}
$d_array += $items
}
Run Code Online (Sandbox Code Playgroud)
我想像一下,如果我使用一个作业调度程序,使我可以运行多个作业,将大大减少处理时间,但是我想让其他人采取快速有效的方法来解决这一问题。
我已经(继承)了一个PowerShell脚本,该脚本通过使用Start-Job
cmdlet和-FilePath
参数调用其他PowerShell脚本来调用它们。例如,我有一个不执行任何操作的脚本:
Start-Sleep -Seconds 86400
Run Code Online (Sandbox Code Playgroud)
我可以通过工作来调用:
PS> Start-Job -Name "Test Job" -FilePath ".\Wait-AllDay.ps1"
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
2 Test Job BackgroundJob Running True localhost Start-Sleep...
PS> Get-Job -Id 2
State : Running
HasMoreData : True
StatusMessage :
Location : localhost
Command : Start-Sleep -Seconds (60*60*24)
JobStateInfo : Running
Finished : System.Threading.ManualResetEvent
InstanceId : 0c0e2c32-cbc5-4d70-b7cb-28771626cf20
Id : 2
Name : Test Job
ChildJobs : {Job3}
PSBeginTime : 25/01/2016 …
Run Code Online (Sandbox Code Playgroud) 我正在使用Invoke-Command
,并且在-ScriptBlock
我正在使用的范围内Start-Job
。我必须使用$Using:var
inside Start-Job
,但会话正在本地会话中查找声明的变量(之前声明Invoke-Command
)。这是我正在做的事情的一个非常简短的例子:
Invoke-Command -ComputerName $computer -ScriptBlock {
$sourcePath = 'C:\Source'
$destPath = 'C:\dest.zip'
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
$includeBaseDirectory = $false
Start-Job -Name "compress_archive" -ScriptBlock {
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::CreateFromDirectory("$using:sourcePath","$using:destPathTemp",$using:compressionLevel,$using:includeBaseDirectory)
}
}
Invoke-Command : The value of the using variable '$using:sourcePath' cannot be retrieved because it has not been set in the local session.
At line:1 char:1
+ Invoke-Command -ComputerName vode-fbtest -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Command], …
Run Code Online (Sandbox Code Playgroud) 我使用下面的代码来显示 PowerShell 作业的结果,超时时间为 120 秒。我想通过合并Write-Progress
(基于完成的作业数量)来增强此代码。我尝试使用此示例作为参考,但是,当我尝试合并该代码时,进度条会在所有作业全部完成后短暂显示。
$Jobs = @()
$ForceStoppedIds = @{}
$Jobs += Get-Job
$Jobs | Wait-Job -Timeout 120 | Out-Null
$Jobs | ?{$_.State -eq 'Running'} | Stop-Job -PassThru | %{$ForceStoppedIds[$_.Id] = $true}
foreach ($Job in $Jobs) {
$Name = $Job.Name
$Output = (Get-Job -Name $Name | Receive-Job)
if ($ForceStoppedIds.Contains($Job.Id)) {
Write-Output "$($Name) - Device unable to process request within 2 minutes"
} else {
Write-Output $Output
}
}
Run Code Online (Sandbox Code Playgroud)