如何从输出中获取版本号

时间:2016-03-10 02:57:13

标签: powershell batch-file

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系统上如何做到这一点的正确方向。

1 个答案:

答案 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'