R& D要求我们为公司的所有系统部署一个新的Outlook插件......但是,有一个问题。如果您有任何其他过时的插件,它们将破坏它们。因此,我们需要确定端点是否安装了插件以及它是什么版本。如果它的安装和版本低于" X"那我们需要更新它。另一个问题是,不是每个人都使用插件,所以我们不能把它推给每个人并称之为一天。
因此我们发现了一个调用WMI并吐出输出的查询,然后我们将其写入文件。正在运行
"wmic product where "Vendor like '%Microsoft%'" get Name, Version > C:\temp\test.txt"
给我们输出:
Name Version First Plug-in for Microsoft Outlook 1.1.9.0 Second Plug-in for Microsoft Outlook 2.0.2.0 Third Plug-in for Microsoft Outlook 1.2.5.0 etc.
我们要做的是解析其中的每一个并将版本写入文件,以便我们可以看看是否需要部署新的插件。
例如:
First.txt contains 1.1.9.0 Second.txt contain 2.0.2.0 etc.
例如,如果Test.txt没有" First"在它里面根本不做文件。我们几乎不得不使用批处理文件来执行此操作,但也应该能够使用PowerShell执行此操作(尽管由于我们的部署系统不是非常强大而需要进行一些调整)。
因此我想知道是否有人能指出我在Windows系统上如何做到这一点的正确方向。
答案 0 :(得分:0)
注意:这个答案回答了所陈述的问题,可能从正则表达式匹配的角度来看是有意义的,但是一个从根本上更好的方法见this。
以下Powershell管道根据要求写入以产品命名的单个文件(扩展名为.txt
)并包含版本号:
Get-Content C:\temp\test.txt | Select-Object -Skip 1 | ForEach-Object `
{
if ($_ -match '^(.*[^ ]) +([^ ]+) *$') {
$fname = $matches[1] + '.txt'
$ver = $matches[2]
$ver > $fname
}
}
请注意,输出文件将写入当前目录。
Get-Content C:\temp\test.txt
通过管道逐行发送文件内容。
Select-Object -Skip 1
跳过标题行。
$_ -match '^(.*[^ ]) +([^ ]+) *$'
将手头的线($_
)与使用捕获组((...)
)的正则表达式进行匹配,以捕获产品名称和版本号子串,可访问通过特殊匹配信息变量$matches
的元素。
$fname = $matches[1] + '.txt'
将.txt
附加到第一个捕获组 - 产品名称 - 并将其存储在变量$fname
中。
$ver = $matches[2]
将版本号 - 第二个捕获组 - 保存在变量$ver
中。
$ver > $fname
只是将版本号写入输出文件。
>
)时,PowerShell会创建UTF-16 LE编码的文件;要使用其他编码,请使用,例如$ver | Out-File -Encoding utf8
。如果您想从cmd.exe
(批处理文件)调用整个PowerShell命令,请使用以下命令:
powershell.exe -noprofile -command "Get-Content C:\temp\test.txt | Select-Object -Skip 1 | ForEach-Object { if ($_ -match '^(.*[^ ]) +([^ ]+) *$') { $fname = $matches[1] + '.txt'; $ver = $matches[2]; $ver > $fname } }"
要仅使用插件名称的第二个以空格分隔的标记作为文件名:
在上面的两个命令中,替换:
$fname = $matches[1] + '.txt'
使用:
$fname = (-split $matches[1])[1] + '.txt'