Quantcast
Channel: The Official Scripting Guys Forum! forum
Viewing all articles
Browse latest Browse all 15028

Powershell: Accepting pipeline input from multiple sources

$
0
0

I'm writing a script that will take a list of server names and return the list of pending Windows updates. I'd like the script to accept input from Get-ADComputer, Get-Content (of a text file with server names), or from the command line.

Right now, I can pass in multiple names from the command line (.\scriptName.ps1 -DNSHostName server1,server2) and get the correct output. With Get-ADComputer, the script works when I'm only passing in one server (Get-ADComputer -filter * | where {$_.name -eq "memwinexch*"} | .\scriptName.ps1). If I try to get multiple servers, I only get updates for one, and I can't tell which, because the $computer variable is blank. Finally, if I use Get-Content, the script only returns updates for the last computer in the list.

How do I sort this out? Thanks.

<# 
.Synopsis
    Get's the list of pending Windows Updates from the local or remote computers.
.DESCRIPTION 
    This script takes a list of Windows computers from the pipeline or as a parameter and gets the list of pending updates.
.NOTES 
    Author: Mike Hashemi
    V1 date: 19 Aug 13
.PARAMETER DNSHostName
    Required parameter. Accepts pipeline input, or a comma-sperated list of computer names.
.PARAMETER OutputType
    Default value is "File". Valid options are "File" and "Screen". This parameter determines where the script will send its output.
.PARAMETER OutputFilePath
    Default value is the logged-on user's desktop. This parameter determines where the script will save the output file, if OutputType is "File".
.EXAMPLE
    .\get-WindowsUpdates-Pending-Parameterized.ps1 -DNSHostName server1,server2
    This example get's the list of pending updates for server1 and server2, then saves the list to a text file on the user's desktop. The output file is called "pendingUpdates_$computer.txt".
.EXAMPLE
    Get-ADComputer -Filter DNSHostName | Where {$_.Name -eq "server1"} | .\get-WindowsUpdates-Pending-Parameterized.ps1 -OutputType Screen
    This example get's the list of pending updates for server1, then outputs the list to the shell.
.EXAMPLE
    Get-Content C:\servers.txt | .\get-WindowsUpdates-Pending-Parameterized.ps1 -OutputFilePath c:\
    This example get's a list of computers from the servers.txt file (one server name per line), then get's the list of pending updates for those server. Finally, the script saves the list to a text file on the c:\ drive. The output file is called "pendingUpdates_$computer.txt".
#>

#Requires -version 2.0 
[CmdletBinding()]
param(
    [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
    [string[]]$DNSHostName,

    [ValidateSet("Screen","File")]
    [string]$OutputType = 'File',

    [string]$OutputFilePath = [Environment]::GetFolderPath("Desktop")
)

#Test if the output file path exists. If not, try to create it.
If (($OutputType -eq "File") -and (-not (Test-Path $OutputFilePath))) {
    Try {
        New-Item $OutputFilePath -Type Directory -ErrorAction Stop | Out-Null
    }
    Catch [System.UnauthorizedAccessException] {
        Write-Host ("You do not have permission to create a file in {0}. The specific error message is: {1}" -f $OutputFilePath,$_.Exception.Message) -ForegroundColor Red
        Return
    }
    Catch {
        Write-Host ("An unexpected error has occurred. The specific error message is: {0}" -f $_.Exception.Message) -ForegroundColor Red
        Return
    }
}

#Get updates for each computer
Foreach ($computer in $DNSHostName) {
Write-Host ("Gathering updates for {0}" -f $computer)
    Try {
        $updateSession = [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session",$computer))
    }
    Catch [UnauthorizedAccessException] {
        Write-Host ("You do not have permission to access {0}. Please try with another account." -f $computer) -ForegroundColor Red
        Continue
    }
    Catch {
        If ($_.Exception -match "800706ba") {
            Write-Host ("Cannot connect to the server: {0}, please check the name and try again." -f $computer) -ForegroundColor Red
            Continue
        }
        Else {
            Write-Host ("Unexpected error connecting to {0}. The specific error message is {1}." -f $computer, $error.Exception) -ForegroundColor Red
            Continue
        }
    }

    #Getting the list of updates
    $updateSearcher = $updateSession.CreateUpdateSearcher()
    $searchResult = $updateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")

    #Setup variables for different types of updates
    $critical = $searchResult.updates | Where {$_.MsrcSeverity -eq "Critical"}
    $important = $searchResult.updates | Where {$_.MsrcSeverity -eq "Important"}
    $other = $searchResult.updates | Where {$_.MsrcSeverity -eq $null}

    If ($searchresult.Updates.Count -eq "0") {
        If ($OutputType -eq "File") {
            ("There are no pending updates for {0}" -f $computer) | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
            Continue
        }
        Else {
            Write-Host ("There are no pending updates for {0}" -f $computer) -ForegroundColor Yellow
            Continue
        }
    }

    #Write results to the output file 
    If ($OutputType -eq "File") {
        ("Updates for {0}:" -f $computer) | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        ("Critical = {0}" -f $critical.count) | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        Foreach ($update in $critical) {
            $update.title | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        }"" | Out-File -FilePath "$OutputFilePath\pendingUpdates_$Computer.txt" -Append
        ("Important = {0}" -f $important.count) | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        Foreach ($update in $important) {
            $update.title | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        }"" | Out-File -FilePath "$OutputFilePath\pendingUpdates_$Computer.txt" -Append
        ("Other = {0}" -f $other.count) | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        Foreach ($update in $other) {
            $update.title | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
        }"--------------------------------" | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append"" | Out-File -FilePath "$OutputFilePath\pendingUpdates_$computer.txt" -Append
    }
    Else {
        #Write results to the shell
        Write-Host ("Updates for {0}:" -f $computer)
        Write-Host ("Critical = {0}" -f $critical.count)
        Foreach ($update in $critical) {
            Write-Host $update.title
        }
        Write-Host ("Important = {0}" -f $important.count)
        Foreach ($update in $important) {
            Write-Host $update.title
        }
        Write-Host ("Other = {0}" -f $other.count)
        Foreach ($update in $other) {
            Write-Host $update.title
        }
        Write-Host "--------------------------------"
        Write-Host ""
    }
}

#Open the output file for each computer
If ($OutputType -eq "File") {
    Foreach ($computer in $DNSHostName) {
        Notepad "$OutputFilePath\pendingUpdates_$computer.txt"
    }
}


Viewing all articles
Browse latest Browse all 15028

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>