将字符串的输出拆分为单独的字符串

时间:2017-09-19 18:40:18

标签: string powershell dns active-directory

我一直在研究一个PowerShell脚本,这让我很难过。脚本有两个部分。

  1. 第一部分是获取域中所有服务器的函数。我们有4个不同的域,所以我分别检查每个域并输出结果。

  2. 第二部分是在特定远程机器上输出软件的功能。在我的情况下,上面函数的输出将被播种到此函数中,以查看服务器是否安装了特定的软件。

  3. 搜索软件的功能正常。我得到所有服务器输出的功能是我遇到的麻烦。

    问题是,当我输出服务器列表(输出正确)时,它会将所有内容输出到一个大的多行字符串...

    例如,假设我有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
    

    提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您的代码正在将服务器名称转换为字符串

$MyServers = Get-ADComputer -Filter 'OperatingSystem -like "Windows*Server*"' -Properties Name -SearchBase $($MySearchBase[$i]) -Server $($MyDomains[$i]) | Format-Table Name -HideTableHeaders | out-string

最后一部分是out-string。不是管道到格式表并将其作为字符串推出,而是保留对象并使用每个对象中的属性来获取每个服务器的名称。

答案 1 :(得分:0)

我最终改写了一些东西并解决了我的问题。为了避免字符串问题,我将结果导出到文本文件然后使用get-content我从文本文件中逐行读取并播种每个服务器以告诉我哪些服务器具有我需要的软件。这是最终结果。

override func viewDidLayoutSubviews() {
    textView.setContentOffset(.zero, animated: false)
}