Powershell数组方法循环和比较?



我有各种各样的计算机,我正在编写一个Powershell脚本,该脚本与服务器上的本地计算机驱动程序存储库安装网络共享,这些存储库作为每台机器的Make和Model保存在自己的单独目录中(例如联想E460,戴尔Latitude E5450等)。

这就是我要做的:

我想要获取计算机的信息(制造和型号)并将其连接到一个字符串中。然后,我希望该字符串然后被引用针对驱动程序目录的数组,如果计算机使+模型匹配,我希望计算机下载该目录内的驱动程序。我来自web开发背景,这里是我通常使用JavaScriptArray.prototype.filter()方法来过滤数组,将$computer$drivers数组中的每个子项目进行比较的地方。

$computer = (gwmi Win32_ComputerSystem).Manufacturer + " " + (dwmi Win32_ComputerSystem).Model
$drivers = Get-ChildItem \zapppc!Drivers

Powershell实现这一目标的最佳方法是什么?Powershell有类似JavaScript的过滤和比较数组方法吗?或者Foreach-match-eq是最有效的写法吗?

谢谢!

您应该能够在没有数组或任何(显式)过滤的情况下完成此操作。

首先,为了效率起见,我将像这样初始化$computer

$computerSystem = gwmi Win32_ComputerSystem -Property 'Manufacturer', 'Model'
$computer = $ComputerSystem.Manufacturer + " " + $computerSystem.Model

如果你想要更花哨,你也可以做…

$computer = $computerSystem.Manufacturer, $computerSystem.Model -join " "

现在,您可以让文件系统为您管理和搜索一系列驱动程序目录,而不是自己管理和搜索驱动程序目录…

$driverDirectory = Get-Item -LiteralPath "\zapppc!Drivers$computer"

如果指定的路径上不存在对象,将抛出错误。你可以像这样修改…

$driverDirectory = Get-Item -LiteralPath "\zapppc!Drivers$computer" -ErrorAction SilentlyContinue
if ($null -ne $driverDirectory)
{
# $driverDirectory exists; copy drivers
}

…或者像这样…

$driverDirectoryPath = "\zapppc!Drivers$computer"
if (Test-Path -Path $driverDirectoryPath)
{
# $driverDirectoryPath exists; copy drivers
}

这样做的唯一真正的缺点是,如果!Drivers是一个巨大的目录(即成千上万的孩子),你反复查找驱动程序目录,那么目录枚举可能会明显慢于缓存结果自己在一个数组中。我猜您的脚本将只复制本地系统的适用驱动程序,所以,就像我说的,我只是让文件系统做它最擅长的事情。

大家晚上好。

直到一个比我更聪明的人出现(这不会很长),我可以试着给你指出正确的方向。

实际上这里有几个选项。您可以使用依赖于bool的条件语句(布尔值-只是一种时髦的说法),以及Where-Object与一些操作符的组合。

让我先发布这个,这样它就不会崩溃(我的屏幕破裂,它的行为不稳定)。我们将从Switch声明开始。如果满足条件,则执行操作。

$computer = (gwmi Win32_ComputerSystem).Manufacturer + " " + (gwmi Win32_ComputerSystem).Model
$drivers = Get-ChildItem \zapppc!Drivers | Select-Object -ExpandProperty Name
Switch ($drivers){
"$computer" {"Found: $_" }

}

我回来了!那么,回到我上节课的地方……你可以使用switch语句,它会在满足特定条件时做一些事情;在这种情况下,一旦它检测到字符串与您正在寻找的匹配,它就会执行从远程PC到本地PC的复制项。见下文:

$computer = (gwmi Win32_ComputerSystem).Manufacturer + " " + (gwmi Win32_ComputerSystem).Model
Switch (Get-ChildItem \zapppc!Drivers){
"$computer" {Copy-Item -Path $_.FullName -Destination C:DriverStore }
}

使用Foreach循环,我们可以遍历每个文件并尝试使用if语句匹配您传递给它的值,一旦找到,在远程PC上对您的PC执行Copy-Item

Foreach($file in (Get-ChildItem \zapppc!Drivers)){
if($file -match  $computer){ Copy-Item -Path $file.FullName -Destination C:DriverStore}
}

接下来,我们只是在-match操作符的帮助下将文件传递到Where-Object,将指定的值与左侧的对象进行匹配。在末尾使用Foreach-Objectcmdlet(不要与Foreach混淆),并使用-Process参数来运行输入对象中的每个元素。然后把与你的电脑匹配的文件夹从远程电脑复制到你的电脑。

$computer = (gwmi Win32_ComputerSystem).Manufacturer + " " + (gwmi Win32_ComputerSystem).Model
Get-ChildItem \zapppc!Drivers | Where-Object {$_.Name -match $computer} |ForEach-Object -process{ Copy-Item -Path $_.fullname -Destination C:DriverStore}

希望这是有意义的,可以让你走上正确的轨道。为了简单起见,我没有提到其他几个方法,但是@Lee_Daily确实提到了.Where()方法,也可以在这种情况下使用。