none
Ajuda Script Powershell + WSUS RRS feed

  • Pergunta

  • Prezados, boa noite!

    Tenho um script em powershell que ele me retorna as seguintes informações:

    FullDomainName";"IPAddress";"OSDescription";"LastSyncTime";"NotInstalledCount";"InstalledPendingRebootCount";"FailedCount";"Installedcount"
    "backupexec.kteste.lan";"192.168.0.231";"Windows Server 2012 R2";"14/12/2016 19:14:01";"4";"0";"0";"165"
    "admin01.kteste.lan";"192.168.0.230";"Windows Server 2012";"14/12/2016 20:59:54";"0";"0";"0";"113"

    Porém as informações dos Campos "NotInstalledCount";"InstalledPendingRebootCount";"FailedCount" está invertido,  as informações do backupexec está no admin01

    O script tem dois foreach onde um deles carrega os campos FullDomainName";"IPAddress";"OSDescription";"LastSyncTime" e o outro foreach os campos "NotInstalledCount";"InstalledPendingRebootCount";"FailedCount"

    Alguém tem alguma ideia de como acertar isso?  Abaixo o script.

    [void][system.reflection.assembly]::LoadWithPartialName('Microsoft.UpdateServices.Administration')

    $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer() 

    $computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope

    $updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope

    $collection = @()

    $Inf01 = {$wsus.GetSummariesPerComputerTarget($updatescope,$computerscope)}.Invoke()

    $Inf02 = {$wsus.GetComputerTargets($computerscope)}.Invoke()

        foreach ($Info02 in $Inf02) {
        
            foreach ($Info01 in $Inf01) {
                $collection += [pscustomobject] @{
                            FullDomainName                     = $Info02.FullDomainName
               IPAddress                            = $Info02.IPAddress
               OSDescription                        = $Info02.OSDescription
               LastSyncTime                       = $Info02.LastSyncTime 
                            
                            NotInstalledCount                   = $Info01.NotInstalledCount
               InstalledPendingRebootCount          = $Info01.InstalledPendingRebootCount
                            FailedCount                       = $Info01.failedcount                
              
                            }

            $Inf01.Remove($Info01)
             
            break
        }
    }

    $collection | export-csv -path c:\teste\clients.csv -Delimiter ";" -Notypeinformation

    quarta-feira, 14 de dezembro de 2016 23:05

Respostas

  • O que acontece neste caso é que você não pode criar um mesmo objeto dentro de dois laços sem ter um critério para amarrar as informações entre cada array de dados.

    É preciso ter uma chave primária para associar a informação do primeiro array com o que se quer no segundo array. Imagine que eu tenha dois arrays de objetos um chamado Array1 e outro chamado Array2. Em Array1 eu tenho os campos ID, Name e Health. Em Array2 eu tenho ID, KB e Status.

    Para se contruir um objeto com informações corretas eu preciso de apenas um laço e nos campos a serem extraídos do Array2, a única coisa que é preciso fazer é procurar em Array2 pelo ID atualmente em Item1.ID e obter a informação do campo desejado.

    ForEach ($Item1 in $Array1) {
        $Properties = @{ID = $Item1.ID
                        Name = $Item1.Name
                        Health = $Item1.Health
                        KB = ($Array2 | ? {$_.ID -eq $Item1.ID}).KB
                        Status = ($Array2 | ? {$_.ID -eq $Item1.ID}).Status
        }
    }

    É claro que a situação acima presume que exista apenas um item em ambos os arrays que tenham o mesmo ID. No caso dos objetos do WSUS, parece que ambos possuem um atributo chamado FullDomainName que trás o nome do computador - este é o campo que pode ser usado como chave primária neste caso.

    quinta-feira, 15 de dezembro de 2016 19:39

Todas as Respostas

  • Olá, conseguiu resolver o problema?
    quinta-feira, 15 de dezembro de 2016 12:01
  • Opa, consegui nada, continua trazendo errado.

    Olha só a saída do script mostrando que o backupexecteste tem 44 atualizações e logo abaixo o console do wsus e as 44 atualizações são do host vsrm

    FullDomainName IPAddress OSDescription LastSyncTime NotInstalledCount InstalledPendingRebootCount FailedCount
    backupexecteste.kteste.lan ::1 Windows Server 2012 R2 15/12/2016 09:29 44 0 0
    admin01.kteste.lan 192.168.0.230 Windows Server 2012 15/12/2016 14:02 0 0 0
    vsrm.kteste.lan 10.0.0.132 Windows Server 2012 R2 15/12/2016 16:06 0 0 0


    

    quinta-feira, 15 de dezembro de 2016 16:21
  • Tente imprimir separadamente as informações dos comandos abaixo para comparar:

    $wsus.GetSummariesPerComputerTarget($updatescope,$computerscope)
    $wsus.GetComputerTargets($computerscope)

    Para dar certo, as listas ter que ter o mesmo tamanho e estarem na mesma ordem. Execute os comandos abaixo antes dos loop para ver a quantidade de itens em cada listagem:

    Write-Host $Inf01.Count
    Write-Host $Inf02.Count

    Talvez tenha que usar um Sort ou algo assim.



    • Editado J. Maurício quinta-feira, 15 de dezembro de 2016 16:59
    quinta-feira, 15 de dezembro de 2016 16:49
  • As duas listas retornam 3 resultados e passando o count também 3.

    Estou pesquisando também como ajustar isso.

    quinta-feira, 15 de dezembro de 2016 17:43
  • Ok. Não tenho como executar esse comando pois não tenho uma infra com WSUS. Pelo jeito cada comando traz a informação numa ordem distinta.
    quinta-feira, 15 de dezembro de 2016 17:53
  • O que acontece neste caso é que você não pode criar um mesmo objeto dentro de dois laços sem ter um critério para amarrar as informações entre cada array de dados.

    É preciso ter uma chave primária para associar a informação do primeiro array com o que se quer no segundo array. Imagine que eu tenha dois arrays de objetos um chamado Array1 e outro chamado Array2. Em Array1 eu tenho os campos ID, Name e Health. Em Array2 eu tenho ID, KB e Status.

    Para se contruir um objeto com informações corretas eu preciso de apenas um laço e nos campos a serem extraídos do Array2, a única coisa que é preciso fazer é procurar em Array2 pelo ID atualmente em Item1.ID e obter a informação do campo desejado.

    ForEach ($Item1 in $Array1) {
        $Properties = @{ID = $Item1.ID
                        Name = $Item1.Name
                        Health = $Item1.Health
                        KB = ($Array2 | ? {$_.ID -eq $Item1.ID}).KB
                        Status = ($Array2 | ? {$_.ID -eq $Item1.ID}).Status
        }
    }

    É claro que a situação acima presume que exista apenas um item em ambos os arrays que tenham o mesmo ID. No caso dos objetos do WSUS, parece que ambos possuem um atributo chamado FullDomainName que trás o nome do computador - este é o campo que pode ser usado como chave primária neste caso.

    quinta-feira, 15 de dezembro de 2016 19:39
  • Pessoal, bom dia!

    Consegui ajustar.

    Desde já agradeço a ajuda e atenção de todos.

    Abraço

    sexta-feira, 16 de dezembro de 2016 12:40