将 schtasks.exe 输出传递到 PowerShell 中的 foreach 循环

发布于 2025-01-10 17:54:08 字数 1206 浏览 0 评论 0原文

我正在使用 powershell5.1,我试图获取远程服务器上运行的一些任务,看看是否有任何任务正在运行。如果有任何正在运行的任务,那么我将使脚本休眠一分钟,然后再次检查,直到我正在检查的所有任务都处于“就绪”状态。

我用什么来查询远程服务器:

$servers = "Server1"
""
foreach($server in $servers)
{
   Invoke-Command -ComputerName $server -ScriptBlock{ 
       schtasks /query /fo list /tn RandomTaskName
   }
}

然后输出这个结果:

HostName:      $server
TaskName:      \RandomTaskName
Next Run Time: 3/1/2022 11:40:00 AM
Status:        Running
Logon Mode:    Interactive/Background

所以我向 FINDSTR“状态:正在运行”添加一个管道,

schtasks /query /fo list /tn RandomTaskName | FIDNSTR "Status: Running"

它只返回字符串。 然后我尝试将输出添加到变量并执行 foreach 循环以查看字符串是否包含“Status: Running”,

$servers = "Server1"
foreach($server in $servers)
{
   Invoke-Command -ComputerName $provider -ScriptBlock{ 
       schtasks /query /fo list /tn RandomTaskName
       }
   $task = $_
   if ("Status: Running" -ccontains $task)
   {
       Wrtite-host "Task is still running"
   }
   else
     {
       Write-Host "Task is NOT running"
     }
}

这不会产生任何结果。当我注释掉“if”和“else”语句时,只有“$task=$_”位于末尾,然后它会导致“状态:正在运行”。

任何人都可以提供有关如何获取远程服务器列表的运行状态的任何见解?

I am using powershell5.1 and I am trying to grab a few tasks running on a remote server and see if any are running. IF there are any running then I will have the script sleep for a minute and then check again until all the tasks I am checking are in Ready status.

What I use to query the remote server:

$servers = "Server1"
""
foreach($server in $servers)
{
   Invoke-Command -ComputerName $server -ScriptBlock{ 
       schtasks /query /fo list /tn RandomTaskName
   }
}

Which then outputs this result:

HostName:      $server
TaskName:      \RandomTaskName
Next Run Time: 3/1/2022 11:40:00 AM
Status:        Running
Logon Mode:    Interactive/Background

So I add a pipe to FINDSTR "Status: Running"

schtasks /query /fo list /tn RandomTaskName | FIDNSTR "Status: Running"

That returns just the string.
Then I try to add the output to a variable and do a foreach loop to see if a string contains "Status: Running"

$servers = "Server1"
foreach($server in $servers)
{
   Invoke-Command -ComputerName $provider -ScriptBlock{ 
       schtasks /query /fo list /tn RandomTaskName
       }
   $task = $_
   if ("Status: Running" -ccontains $task)
   {
       Wrtite-host "Task is still running"
   }
   else
     {
       Write-Host "Task is NOT running"
     }
}

Which results in nothing. When I comment out the "if" and "else" statements so only "$task=$_" is at the end, then it results in "Status: Running".

Anyone can give any insight as to how to grab the running status for a list of remote servers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

剩一世无双 2025-01-17 17:54:08

当我看到这个问题的时候,我的好奇心真的达到了顶峰。我更多地使用工作站而不是服务器,但一切都应该大致相同。

这完全是我解决自己问题的方法,因此可能不适合您的需求 - 抱歉。但也许我的代码可以给你一些关于如何做你想做的事情的想法。

此代码:

  1. 有一个名为 Invoke-InBackgroundOnMachines 的函数,该函数接受机器数组、参数列表和脚本块。
  2. Invoke-InBackgroundOnMachines 从运行脚本块的每台远程计算机获取管道内容并将其返回到管道上。
  3. Invoke-InBackgroundOnMachines 在尝试在每台计算机上运行脚本块之前检查它是否可以连接到每台计算机。无法连接到的机器将以逗号分隔的文本“Machine”、“NoConnection”、“NoConnection”返回到管道上。它可以连接的机器存储在 LiveMachines 数组中,该数组随后与脚本块和参数列表一起传递给 Invoke-Command。
  4. 我还没有弄清楚的一件事是如何最好地处理未启用 WinRM 的计算机。 Invoke-Command 在访问禁用 WinRM 的计算机时会引发错误。这是我第一次尝试运行远程脚本块,所以还有很多东西需要弄清楚。
  5. 脚本块本身比我预期的要大得多。但它的作用是以逗号分隔的格式返回任务的状态。
  6. 这不是经过正确测试的代码。今天早上我就从cervan12的代码开始写。所以请记住这一点。
# Used Example 8 from following URL
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-5.1
$SchTasksScriptBlock = {
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$TaskNameToFind
    )
    function CommaDelimited {
        param (
            [Parameter(Mandatory = $true, Position = 0)]
            [string[]]$Tokens
        )
        $Return = ''
        foreach ($Token in $Tokens) {
            $Return += ", `"$Token`""
        }
        $Return.Substring(2)
    }
    $STReturn = SCHTASKS /Query /FO LIST /TN $TaskNameToFind 2>$null
    if ($LASTEXITCODE -eq 0) {        
        $HostName = ''
        switch -Regex ($STReturn) {
            '(?i)^\s*hostname:\s*(?<HostName>.*)\s*

使用示例:

$List = @(  'Machine1', 'Machine1' )
Invoke-InBackgroundOnMachines $List '\AlertusSecureDesktopLauncher' $SchTasksScriptBlock

管道上返回的示例结果:

"Machine1", "\AlertusSecureDesktopLauncher", "Ready"
"Machine2", "\AlertusSecureDesktopLauncher", "Ready"
{ if ($HostName -ne '') { CommaDelimited $HostName, $TaskName, $Status } $HostName = $Matches.HostName continue } '(?i)^\s*taskname:\s*(?<TaskName>.*)\s*

使用示例:


管道上返回的示例结果:


 {
                $TaskName = $Matches.TaskName
                continue
            }
            '(?i)^\s*status:\s*(?<Status>.*)\s*

使用示例:


管道上返回的示例结果:


 {
                $Status = $Matches.Status
                continue
            }
            Default {
                continue
            }
        }
        if ($HostName -ne '') { CommaDelimited $HostName, $TaskName, $Status }
    } else {
        $HostName = HostName
        CommaDelimited $HostName, $TaskNameToFind, 'Missing'
    }
}
function Invoke-InBackgroundOnMachines {
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string[]]$Machines,
        [Parameter(Mandatory = $true, Position = 1)]
        [object[]]$ArgumentList,
        [Parameter(Mandatory = $true, Position = 2)]
        [scriptblock]$ScriptBlock
    )
    [string[]]$LiveMachines = @()
    foreach ($Machine in $Machines) {
        if(Test-Connection -ComputerName $Machine -Quiet) {
            $LiveMachines += $Machine
        } else {
            "`"$Machine`", `"NoConnection`",`"NoConnection`""
        }
    }
    If($LiveMachines.Count -gt 0) {
        $Session = New-PSSession -ComputerName $LiveMachines
        $null = Invoke-Command -Session $Session -ScriptBlock $ScriptBlock -AsJob -ArgumentList $ArgumentList
        Get-Job | Wait-Job | Receive-Job
    }
}

使用示例:

管道上返回的示例结果:

When I saw this question, it really peaked my curiosity. I'm working more with workstations than servers, but everything should be about the same.

This is entirely my approach to solve my own problems, so it may not fit your needs - sorry. But perhaps my code can give you some ideas on how to do what you want.

This code:

  1. Has a function called Invoke-InBackgroundOnMachines that takes an array of machines, a list of arguments, and a scriptblock.
  2. Invoke-InBackgroundOnMachines gets pipeline content from each remote machine that the scriptblock is ran on and returns it on the pipeline.
  3. Invoke-InBackgroundOnMachines checks to see if it can connect to each machine before trying to run the scriptblock on it. Machines that it cannot connect to are returned on the pipeline in a comma delimited text of "Machine", "NoConnection", "NoConnection". Machines that it can connect to are stored in the LiveMachines array, which is later handed to Invoke-Command, along with the scriptblock and argument list.
  4. The one thing I haven't figured out yet is how to best deal with computers that do not have WinRM enabled. Invoke-Command throws errors when it hits a computer with WinRM disabled. This is my first attempt at running remote script blocks, so still have a lot to figure out.
  5. The scriptblock itself wound up being a lot larger than I was expecting. But it does the job of returning the status of tasks in a comma delimited format.
  6. This is not properly tested code. I started with cervan12's code this morning and started writing. So keep that in mind.
# Used Example 8 from following URL
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-5.1
$SchTasksScriptBlock = {
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$TaskNameToFind
    )
    function CommaDelimited {
        param (
            [Parameter(Mandatory = $true, Position = 0)]
            [string[]]$Tokens
        )
        $Return = ''
        foreach ($Token in $Tokens) {
            $Return += ", `"$Token`""
        }
        $Return.Substring(2)
    }
    $STReturn = SCHTASKS /Query /FO LIST /TN $TaskNameToFind 2>$null
    if ($LASTEXITCODE -eq 0) {        
        $HostName = ''
        switch -Regex ($STReturn) {
            '(?i)^\s*hostname:\s*(?<HostName>.*)\s*

Example use:

$List = @(  'Machine1', 'Machine1' )
Invoke-InBackgroundOnMachines $List '\AlertusSecureDesktopLauncher' $SchTasksScriptBlock

Example results returned on the Pipeline:

"Machine1", "\AlertusSecureDesktopLauncher", "Ready"
"Machine2", "\AlertusSecureDesktopLauncher", "Ready"
{ if ($HostName -ne '') { CommaDelimited $HostName, $TaskName, $Status } $HostName = $Matches.HostName continue } '(?i)^\s*taskname:\s*(?<TaskName>.*)\s*

Example use:


Example results returned on the Pipeline:


 {
                $TaskName = $Matches.TaskName
                continue
            }
            '(?i)^\s*status:\s*(?<Status>.*)\s*

Example use:


Example results returned on the Pipeline:


 {
                $Status = $Matches.Status
                continue
            }
            Default {
                continue
            }
        }
        if ($HostName -ne '') { CommaDelimited $HostName, $TaskName, $Status }
    } else {
        $HostName = HostName
        CommaDelimited $HostName, $TaskNameToFind, 'Missing'
    }
}
function Invoke-InBackgroundOnMachines {
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string[]]$Machines,
        [Parameter(Mandatory = $true, Position = 1)]
        [object[]]$ArgumentList,
        [Parameter(Mandatory = $true, Position = 2)]
        [scriptblock]$ScriptBlock
    )
    [string[]]$LiveMachines = @()
    foreach ($Machine in $Machines) {
        if(Test-Connection -ComputerName $Machine -Quiet) {
            $LiveMachines += $Machine
        } else {
            "`"$Machine`", `"NoConnection`",`"NoConnection`""
        }
    }
    If($LiveMachines.Count -gt 0) {
        $Session = New-PSSession -ComputerName $LiveMachines
        $null = Invoke-Command -Session $Session -ScriptBlock $ScriptBlock -AsJob -ArgumentList $ArgumentList
        Get-Job | Wait-Job | Receive-Job
    }
}

Example use:

Example results returned on the Pipeline:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文