我正在尝试遍历服务器阵列,并将此测试路径命令作为后台线程运行。它必须是一个线程,因为我将对其进行超时监视,并在超时后终止该线程。
我无法获得变量的返回值,也不知道如何在多台计算机上使用单独的变量,或者我是否正确传递了变量。在c#中,我将使用线程集合,但似乎无法弄清楚Powershell的语法。
foreach ($server in $servers)
{
Write-Host $server;
$scriptBlock =
{
$returnVal = Test-Path "\\$server\c$";
return $returnVal;
}
$remoteReturnVal = Invoke-Command -ComputerName [Environment]::MachineName -ScriptBlock { $script } –AsJob;
}
这是我如何使用c#在Powershell中进行操作(以下工作原理)
$shareCheck =
@'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace powershellConsoleForm
{
public class shares
{
public List<string> shareExists(List<string> servers, int timeOut)
{
List<string> returnValue = new List<string>();
foreach (string server in servers)
{
string path = @"\\" + server + @"\c$";
Func<bool> func = () => Directory.Exists(path);
Task<bool> task = new Task<bool>(func);
task.Start();
if (task.Wait(timeOut))
{
//return task.Value;
Console.Write(" ");
Console.Write("success " + task.Result);
Console.Write(" ");
returnValue.Add(server + "|" + task.Result.ToString());
}
else
{
Console.Write("timeout");
returnValue.Add(server + "|timeout");
}
}
Console.Write("Done");
return returnValue;
}
}
}
'@
try
{
$shareChecker = New-Object powershellConsoleForm.shares;
}
catch
{
$assemblies = ("System", "System.Collections", "System.ComponentModel", "System.Data", "System.Drawing", "System.IO", "System.Linq", "System.Management.Automation", "System.Security", "System.Threading.Tasks", "System.Windows.Forms", "System.Threading", "System.Collections.Concurrent", "System.Security.Principal");
Add-Type -TypeDefinition $shareCheck -ReferencedAssemblies $assemblies -Language CSharp
$shareChecker = New-Object powershellConsoleForm.shares;
}
$servers = @("server1", "server2", "server3", "server4", "server5");
$timeOut = 11000;
[int] $counter = 0;
do
{
$counter ++;
Write-Host $counter;
$shareAvailibilities = $shareChecker.shareExists($servers, $timeOut);
foreach ($shareAvailibility in $shareAvailibilities)
{
Write-Host $shareAvailibility;
}
Write-Host " ";
Write-Host " ";
Sleep 5;
}while ($true)
答案 0 :(得分:1)
首先,默认情况下,Invoke-Command返回脚本块的输出。因此,您的脚本块可能类似于$ScriptBlock = {Test-Path "\\$server\c$"}
。
然后,Invoke-Command行存在多个问题。
Get-Job
访问工作结果。-JobName $server
,以便更轻松地按服务器查看结果。$env:COMPUTERNAME
,因为它在眼睛和操作上都更容易一些。$script
变量包装在脚本块中(如果它已经是脚本块)。取下花括号。但是,由于该命令非常简单,因此保留括号并用该命令替换变量可能更有意义。这是根据我的调整(以及一些格式调整)而得到的脚本的修订版本:
foreach ($server in $servers) {
Write-Host $server
Invoke-Command -ScriptBlock { Test-Path "\\$server\c$" } –AsJob -JobName $server
}
Get-Job
我正在考虑它,由于您只是在本地计算机上运行它们,因此仅使用Start-Job会更有意义:
foreach ($server in $servers) {
Write-Host $server
Start-Job -Name $server -ScriptBlock { Test-Path "\\$server\c$" }
}
Get-Job
然后要获取作业本身的结果,可以使用Receive-Job。用管道将Get-Job传递到Receive-Job,或通过名称Receive-Job -Name <servername>