【发布时间】:2017-09-19 18:40:18
【问题描述】:
我一直在编写一个 powershell 脚本,这真的让我大吃一惊。脚本分为两部分。
第一部分是获取域中所有服务器的函数。我们有 4 个不同的域,所以我分别检查每个域并输出结果。
第二部分是在特定远程机器上输出软件的功能。在我的例子中,上面函数的输出将被植入到这个函数中,以查看服务器是否安装了特定的软件。
软件搜索功能正常。我得到所有服务器输出的功能是我遇到的问题。
问题是,当我输出服务器列表(输出正确)时,它会将所有内容输出到一个大的多行字符串中......
例如,假设我有 5 台服务器:(ServerA、ServerB、ServerC、ServerD、ServerE)。
当我运行代码时,我会得到每个域的所有服务器的输出,如下所示:
TestA.com
ServerA
ServerB
ServerC
ServerD
ServerE
TestB.com
ServerA
ServerB
ServerC
ServerD
ServerE
TestC.com
ServerA
ServerB
ServerC
ServerD
ServerE
TestD.com
ServerA
ServerB
ServerC
ServerD
ServerE
但是每个域输出都是 1 个字符串,因此我无法将其播种到检查软件的函数中,因为它试图在“ServerA、ServerB、ServerC、ServerD、ServerE”中找到它,而不是单独在每个服务器中找到它。
我希望这是有道理的。这是我获取服务器列表的代码。
#Clear Screen
CLS
function Get-Servers
{
#Variables
[array]$MyDomains="TestA.com","TestB.com","TestC.com","TestD.com"
[array]$MySearchBase="dc=TestA,dc=com","dc=TestB,dc=com","dc=TestC,dc=com","dc=TestD,dc=com"
for($i=0; $i -lt $MyDomains.Count; $i++)
{
Write-Output $($MyDomains[$i])
$MyServers = Get-ADComputer -Filter 'OperatingSystem -like "Windows*Server*"' -Properties Name -SearchBase $($MySearchBase[$i]) -Server $($MyDomains[$i]) | Format-Table Name -HideTableHeaders | out-string
foreach ($MyServer in $MyServers)
{
$MyServer
pause
}
}
}
#Get list of servers
Get-Servers
如何将每个服务器的输出分别存储在“$MyServer”变量中?
编辑: 这是我查找远程软件的功能
function Get-RemoteRegistryProgram
{
<#
.Synopsis
Uses remote registry to read installed programs
.DESCRIPTION
Use dot net and the registry key class to query installed programs from a
remote machine
.EXAMPLE
Get-RemoteRegistryProgram -ComputerName Server1
#>
[CmdletBinding()]
Param
(
[Parameter(
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[string[]]
$ComputerName = $env:COMPUTERNAME
)
begin
{
$hives = @(
[Microsoft.Win32.RegistryHive]::LocalMachine,
[Microsoft.Win32.RegistryHive]::CurrentUser
)
$nodes = @(
"Software\Microsoft\Windows\CurrentVersion\Uninstall",
"Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
}
process
{
$ComputerName
forEach ($computer in $ComputerName)
{
forEach($hive in $hives)
{
try
{
$registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive,$computer)
}
catch
{
throw $PsItem
}
forEach($node in $nodes)
{
try
{
$keys = $registry.OpenSubKey($node).GetSubKeyNames()
forEach($key in $keys)
{
$displayname = $registry.OpenSubKey($node).OpenSubKey($key).GetValue('DisplayName')
if($displayname)
{
$installedProgram = @{
# ComputerName = $computer
DisplayName = $displayname
# Version = $registry.OpenSubKey($node).OpenSubKey($key).GetValue('DisplayVersion')
}
New-Object -TypeName PSObject -Property $installedProgram
}
}
}
catch
{
$orginalError = $PsItem
Switch($orginalError.FullyQualifiedErrorId)
{
'InvokeMethodOnNull'
{
#key maynot exists
}
default
{
throw $orginalError
}
}
}
}
}
}
}
end
{
}
}
编辑 2:
如果我像这样修改我的服务器功能:
for($i=0; $i -lt $MyDomains.Count; $i++)
{
Write-Output $($MyDomains[$i])
$MyServers = Get-ADComputer -Filter 'OperatingSystem -like "Windows*Server*"' -Properties Name -SearchBase $($MySearchBase[$i]) -Server $($MyDomains[$i]) | Format-Table Name -HideTableHeaders
foreach ($MyServer in $MyServers)
{
Get-RemoteRegistryProgram -ComputerName $MyServer
}
}
我收到以下错误:
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found.
"
At line:47 char:21
+ $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IOException
提前感谢您的帮助!
【问题讨论】:
-
无需重新发明轮子。如果你想在远程计算机上安装软件,你可以使用我不久前写的脚本:Auditing 32-Bit and 64-Bit Applications with PowerShell。
-
谢谢。我并不是说听起来无知,但我正在尝试运行它并且遇到了一些麻烦。我有一个我尝试使用的 server.txt 文件。获取内容 u:\scripts\servers.txt | get-installedapp2 -Publisher "SysAid" 你的代码出错了。
-
1) 您没有说出是什么错误(请记住,没有人可以看到您的屏幕)。 2)
2是从哪里来的Get-InstalledApp的末尾?脚本名称末尾没有2。 -
这是你的函数: function get-installedapp2($computerName) { 在你的过程中我看到: if ($PIPELINEINPUT) { get-installedapp2 $_ } else { $ComputerName | foreach-object { get-installedapp2 $_ } }
-
欢迎阅读这篇文章。它提供了示例。
标签: string powershell dns active-directory