1

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

这是我正在尝试做的事情:

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

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

完成此任务的最佳方法是 Powershell?Powershell 有类似 JavaScript 的过滤和比较 Array 方法吗?或者将是Foreach -match或是-eq最有效的编写方式?

谢谢!

4

2 回答 2

2

你好,晚上好。

直到有人比我聪明得多(不会很长),我可以尝试为您指明正确的方向。

你实际上有几个选择。您可以使用依赖于布尔值(布尔值 - 只是一种时髦的说法)的条件语句,并Where-Object结合一些运算符。

让我先发布这个,这样它就不会在我身上崩溃(我的屏幕裂了,它的表现很不稳定)。我们将从Switch声明开始。如果满足条件,做某事。

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

我回来了!所以,回到我离开的地方……你可以使用 switch 语句,它会在满足特定条件时执行某些操作;在这种情况下,一旦它检测到字符串与您要查找的内容匹配,它就会执行从远程 PC 到本地 PC 的复制项。见下文:

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

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

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

接下来,我们只是在操作员Where-Object的帮助下将文件传递给-match,将为其指定的值与左侧的对象进行匹配。最后使用Foreach-Objectcmdlet(不要与 混淆Foreach)和参数-Process来运行输入对象内的每个元素。然后将与您的 PC 匹配的文件夹从远程 PC 复制到您的文件夹。

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

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

于 2021-02-16T00:32:55.213 回答
2

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

首先,为了效率,我会这样初始化$computer......

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

如果你想变得花哨,你也可以这样做......

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

现在,您可以让文件系统为您执行此操作,而不是自己管理和搜索驱动程序目录数组...

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

如果指定路径中不存在任何对象,这将引发错误。你可以这样对抗...

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

……或者像这样……

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

The only real downside of doing it this way instead of what you proposed is that if !Drivers\ is a huge directory (i.e. thousands of children) and you're repeatedly looking up driver directories then that directory enumeration could be noticeably slower than caching the results yourself in an array. I'm guessing your script will only be copying the applicable drivers for the local system so, like I said, I'd just let the filesystem do what it does best.

于 2021-02-16T05:01:54.997 回答