标签: powershell-jobs

如何调用Start-Job,它取决于与调用Start-Job的函数相同的PowerShell模块中的函数?

我正在编写一些PowerShell,以便在单个模块中与AWS API进行通信.我编写了一个函数,Get-CloudFormation它返回CloudFormation的状态.我写了另一个函数,Delete-CloudFormation在启动了一个delete-CF API请求后,尝试启动一个使用my轮询CloudFormation状态的作业Get-CloudFormation.

我打电话Export-ModuleMemberGet-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 jobs powershell-2.0 powershell-jobs

8
推荐指数
1
解决办法
7187
查看次数

如何从Powershell作业捕获.NET跟踪输出?

我使用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 trace powershell-jobs

7
推荐指数
1
解决办法
1606
查看次数

在PowerShell中处理大型阵列

我很难理解在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)

我想像一下,如果我使用一个作业调度程序,使我可以运行多个作业,将大大减少处理时间,但是我想让其他人采取快速有效的方法来解决这一问题。

arrays powershell powershell-jobs

7
推荐指数
1
解决办法
201
查看次数

我如何知道“启动作业”命令启动了哪些进程?

我已经(继承)了一个PowerShell脚本,该脚本通过使用Start-Jobcmdlet和-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)

powershell jobs process powershell-jobs

5
推荐指数
1
解决办法
2573
查看次数

$Using:var 在 Invoke-Command 内的 Start-Job 中

我正在使用Invoke-Command,并且在-ScriptBlock我正在使用的范围内Start-Job。我必须使用$Using:varinside 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 invoke-command powershell-jobs

4
推荐指数
1
解决办法
2318
查看次数

将写入进度添加到获取作业/等待作业

我使用下面的代码来显示 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)

powershell start-job powershell-jobs progress-bar

2
推荐指数
1
解决办法
1294
查看次数