获取 MS Office 列表
Get a List of MS Office
好的,我正在尝试列出所有 Office 版本以及每个版本的数量。我们正在迁移到 Windows 10,我正试图说服他将 Office 升级到 2016。我们的 Office 老到 2010。我需要一份清单,列出每个版本的数量。即使我能得到什么电脑有什么版本的列表。我尽量不 运行 对每台计算机单独进行审核,我们有 200 台计算机。
我尝试了几种不同的方法。
Get-ADComputer -Filter * -Property * | Select-Object Name |
Export-CSV ADcomputerslist.csv -NoTypeInformation -Encoding UTF8
这实际上并没有保存到文件
foreach ($computer in (Get-Content "c:\computers.txt")){
Write-Verbose "Working on $computer..." -Verbose
Invoke-Command -ComputerName "$Computer" -ScriptBlock {
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail* |
Select-Object DisplayName, DisplayVersion, Publisher
} | export-csv C:\results.csv -Append -NoTypeInformation
}
通常认为使用 Get-WmiObject
检查 Win32_Product
class 是不安全的,因为这可能会无意中触发软件修复安装。检查已安装程序的注册表更安全:
# We need to check for both 64-bit and 32-bit software
$regPaths = "HKLM:\SOFTWARE\Wow6432node\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
# Get the name of all installed software registered in the registry with Office in the name
# (you can search for exact strings if you know them for specific versions)
$regPaths | Foreach-Object {
( Get-ItemProperty "${_}\*" DisplayName -EA SilentlyContinue ).DisplayName | Where-Object {
$_ -match 'office'
}
}
它的工作方式是,对于两个注册表路径,我们希望从 $regPaths
的基本路径下的每个键中获取 DisplayName
值(这些主要是 GUID 命名的键,仅通过名称识别软件没有多大价值)。我们忽略错误,因为它们会使输出混乱,并且对于此操作,预计某些键可能没有 DisplayName
属性。我们不关心这些。
一旦我们为所有子项枚举了 DisplayName
,我们要过滤掉名称中没有 'Office' 的子项。请注意,-match
运算符不区分大小写,因此大小写在这里无关紧要。所以 Where-Object
子句只有 return 的一个 DisplayName
在其中找到字符串 office
。 如果您知道所支持的每个 Office 版本的确切 DisplayName 字符串,则可以调整此正则表达式,因为本质上这将 return 名称中带有 Office
的任何内容。
我会这样做:-
首先启动WinRM服务
Get-Service -Name WinRM -ComputerName machinename | Start-service
然后一旦我们有了它,我们就可以查询 WinRM 以获取所有已安装的应用程序。
Get-CimInstance -ComputerName machinename -ClassName win32_product | Select-Object PSComputerName, Name, PackageName, InstallDate
然后最好在完成后禁用 WinRM
Get-Service -Name WinRM -ComputerName df-ps-sitpc17 | Stop-service
作为替代方案,您可以读取 Word 等 Office 应用程序之一的 (default)
注册表值并翻译版本号:
foreach ($computer in (Get-Content "c:\computers.txt")){
Write-Verbose "Working on computer '$computer'..." -Verbose
Invoke-Command -ComputerName $computer -ScriptBlock {
(Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Word.Application\CurVer").'(default)' | ForEach-Object {
[PsCustomObject] @{
'Computer' = $computer
'OfficeVersion' =
switch ([int]($_ -split '\.')[-1]) {
16 {'MS Office 2016 OR MS Office 2019 or MS Office 365'; break}
15 {'MS Office 2013'; break}
14 {'MS Office 2010'; break}
12 {'MS Office 2007'; break}
11 {'MS Office 2003'}
}
}
}
}
}
输出(类似于):
Computer OfficeVersion
-------- -------------
PC_01 MS Office 2013
PC_02 MS Office 2010
遗憾的是,Office 2019 和 Office 2016 不再通过此注册表值中的不同版本号来区分..
好的,我正在尝试列出所有 Office 版本以及每个版本的数量。我们正在迁移到 Windows 10,我正试图说服他将 Office 升级到 2016。我们的 Office 老到 2010。我需要一份清单,列出每个版本的数量。即使我能得到什么电脑有什么版本的列表。我尽量不 运行 对每台计算机单独进行审核,我们有 200 台计算机。
我尝试了几种不同的方法。
Get-ADComputer -Filter * -Property * | Select-Object Name |
Export-CSV ADcomputerslist.csv -NoTypeInformation -Encoding UTF8
这实际上并没有保存到文件
foreach ($computer in (Get-Content "c:\computers.txt")){
Write-Verbose "Working on $computer..." -Verbose
Invoke-Command -ComputerName "$Computer" -ScriptBlock {
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365ProPlusRetail* |
Select-Object DisplayName, DisplayVersion, Publisher
} | export-csv C:\results.csv -Append -NoTypeInformation
}
通常认为使用 Get-WmiObject
检查 Win32_Product
class 是不安全的,因为这可能会无意中触发软件修复安装。检查已安装程序的注册表更安全:
# We need to check for both 64-bit and 32-bit software
$regPaths = "HKLM:\SOFTWARE\Wow6432node\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
# Get the name of all installed software registered in the registry with Office in the name
# (you can search for exact strings if you know them for specific versions)
$regPaths | Foreach-Object {
( Get-ItemProperty "${_}\*" DisplayName -EA SilentlyContinue ).DisplayName | Where-Object {
$_ -match 'office'
}
}
它的工作方式是,对于两个注册表路径,我们希望从 $regPaths
的基本路径下的每个键中获取 DisplayName
值(这些主要是 GUID 命名的键,仅通过名称识别软件没有多大价值)。我们忽略错误,因为它们会使输出混乱,并且对于此操作,预计某些键可能没有 DisplayName
属性。我们不关心这些。
一旦我们为所有子项枚举了 DisplayName
,我们要过滤掉名称中没有 'Office' 的子项。请注意,-match
运算符不区分大小写,因此大小写在这里无关紧要。所以 Where-Object
子句只有 return 的一个 DisplayName
在其中找到字符串 office
。 如果您知道所支持的每个 Office 版本的确切 DisplayName 字符串,则可以调整此正则表达式,因为本质上这将 return 名称中带有 Office
的任何内容。
我会这样做:-
首先启动WinRM服务
Get-Service -Name WinRM -ComputerName machinename | Start-service
然后一旦我们有了它,我们就可以查询 WinRM 以获取所有已安装的应用程序。
Get-CimInstance -ComputerName machinename -ClassName win32_product | Select-Object PSComputerName, Name, PackageName, InstallDate
然后最好在完成后禁用 WinRM
Get-Service -Name WinRM -ComputerName df-ps-sitpc17 | Stop-service
作为替代方案,您可以读取 Word 等 Office 应用程序之一的 (default)
注册表值并翻译版本号:
foreach ($computer in (Get-Content "c:\computers.txt")){
Write-Verbose "Working on computer '$computer'..." -Verbose
Invoke-Command -ComputerName $computer -ScriptBlock {
(Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\Word.Application\CurVer").'(default)' | ForEach-Object {
[PsCustomObject] @{
'Computer' = $computer
'OfficeVersion' =
switch ([int]($_ -split '\.')[-1]) {
16 {'MS Office 2016 OR MS Office 2019 or MS Office 365'; break}
15 {'MS Office 2013'; break}
14 {'MS Office 2010'; break}
12 {'MS Office 2007'; break}
11 {'MS Office 2003'}
}
}
}
}
}
输出(类似于):
Computer OfficeVersion -------- ------------- PC_01 MS Office 2013 PC_02 MS Office 2010
遗憾的是,Office 2019 和 Office 2016 不再通过此注册表值中的不同版本号来区分..