Diese Seite

Pipeline

  • Virtual Memory

    Get-Process | Sort-Object WorkingSet | Select-Object -First 5
    
  • Largest File

    Get-ChildItem -Recurse | Where-Object { $_.Length -gt 10MB } |
    Sort-Object Length -Descending | Select-Object -First 10
    
  • Foreach: Foreach-Objekt besrbeitet die Elemente der Pipeline sofort

    # ForEach-Object lists each element in a pipeline:
    Dir C:\ -recurse | ForEach-Object { $_.name }
    
  • Alias:

    Get-Alias | where-object { $_.definition -eq "get-process" }
    
  • 20 MByte-Prozesse

    get-process | where-object {$_.WorkingSet64 -gt 20MB }
    ps | ? {$_.ws -gt 20MB }
    
  • Sortiert nach Größee

    ps | ? {$_.ws -gt 20MB } | sort ws
    
  • Ausgabe Produktversion

    ps | select company, name, product, productversion
    
  • Dateien

    Get-Childitem h:\daten -filter *.doc -r
    | Where-Object { $_.Length -gt 40000 }
    | Select-Object Name, Length
    | Sort-Object Length
    | export-csv p:\GrosseWordDateien.csv -notype
    
  • Geben Sie alle Unterordner bis zu einer bestimmten Tiefe aus, ausgehend vom jeweils aktuellen Ordner

$Cred = New-Object System.Management.Automation.PSCredential “Administrator”, $Pw

gci -recurse | ? {$_.PSisContainer -eq $true} | where{
       if(($_.fullname.split("\")).count -le 4)
       {
               write-host $_.fullname
       }
}
  • Sie wollen prüfen, ob auf bestimmten Rechnern innerhalb ihres LANs Software bestimmter Hersteller vorhanden ist. Schreiben Sie ein entsprechendes Skript

    ########################################
    # The PowerShell script inventories the installed software
    # of a producer on n computer systems
    # (C) Dr. Holger Schwichtenberg
    ########################################
    $Producer = "*Microsoft*"
    $EntryFilename = "computernames.txt"
    $OutputFilename = "Softwareinventory.csv"
    $pw = Read-Host -AsSecureString
    
    
    
    
    # Import of computer names
    $Computernames = Get-Content "computernames.txt"
    $Computernames | foreach {
           if (Ping($_))
           {
                   Write-Host "Inventorize software for computer $_ ..."
                   # Fetching of installed MSI packages on all computers
    
                   $Cred = New-Object System.Management.Automation.PSCredential $_\Administrator, $Pw
    
                   $Software = foreach { get-wmiobject win32_product -computername $_ -credential $Cred }
                   | where { $_.vendor -like $Producer }
                   # Export in CSV
                   $Software | export-csv $OutputFileName -notypeinformation
           }
           else
           {
                   Write-Error "Computer not accessible!"
           }
    }
    # Execute Ping
    function Ping
    {
           $status = Get-WmiObject Win32_PingStatus -�lter "Address='$args[0]'" |
           select StatusCode
           return $status.Statuscode -eq 0
    }
    

Das Skript ist in mehrere Teile gegliedert:

  1. Function Ping

    # Execute Ping
    function Ping
    {
           $status = Get-WmiObject Win32_PingStatus -�lter "Address='$args[0]'" |
           select StatusCode
           return $status.Statuscode -eq 0
    }
    

    Erhält als Parameter einen Computernamen, ermittelt den Statuscode und gibt true zurück, wenn der Computer erreichbar ist

  2. Einstieg in das Skript

    $Producer = "*Microsoft*"
    $Entry�lename = "computernames.txt"
    $Output�lename = "Softwareinventory.csv"
    # Import of computer names
    $Computernames = Get-Content "computernames.txt"
    

    Definition von einigen Variablen Lesen der zu überprüfenden Computernamen aus einer Textdatei

  3. Informationsbeschaffung

    $Computernames | foreach {
      if (Ping($_))
      {
            Write-Host "Inventorize software for computer $_ ..."
            # Fetching of installed MSI packages on all computers
            $Software = foreach { get-wmiobject win32_product -computername $_ }
            | where { $_.vendor -like $Producer }
            # Export in CSV
            $Software | export-csv "Softwareinventar.csv" -notypeinformation
      }
      else
      {
            Write-Error "Computer not accessible!"
      }
    }
    

    Über eine Pipeline werden die Computernamen nacheinander aufgerufen Bei erfolgreichem Ping wird per WMI der Remote-Computer auf das Vorhandensein des Herstellernamens abgefragt. Bei Vorhandensein wird es als Ergebnis in eine CSV-Datei geschrieben.

  • Erweitern Sie obiges Skript um die Abfrage nach bestimmten Softwarenamen bzw. Versionsständen.

    function Get-IsInstall($Application, $Computer, $Version)
    {
           $a = (Get-WmiObject -Class Win32_Product -Filter
           "Name='$Application' and Version='$Version'" -computername
           $Computer)
           return ($a -ne $null)
    }
    $e = Get-IsInstall "QuickTime" "E01" "7.2.0.240"
    if ($e)
    {
           "Software is installed!"
    }
    else
    {
           "Software is not installed!"
    }
    
  • I needed to merge 365 CSV files that represent daily weather data sets into one CSV file that contains all the data accumulated during one year. Each of the daily CSV files had a header row. The yearly file should only have one. Filtering out rows is a perfect application of the PowerShell filter functions. Übersetzen Sie den anglischen Text sinngemä߸ und schreiben Sie ein entsprechendes Skript.

This is where PowerShell’s pipeline programming is shining. It only takes a Filter function definition, inserting it into an pre-existing pipeline and you are done.

Here is the sample script:

http://www.tellingmachine.com/post/Using-PowerShell-Filter-functions-to-filter-out-header-rows-CSV-file-merges.aspx

#Filter Function filters out records that start with "Time"
Filter Filter-Header
{
        if($_ -match "^Time")
        {
                $_ | out-null
        }
        else
        {
                $_
        }
}

cd "C:\WeatherStation\FilterTest"

#Initializing yearly file
$YearlyFileName = "Weather2009.csv"
#Set the header only once in the yearly file
Set-Content -Path $YearlyFileName -value "Time,TemperatureF,DewpointF,PressureIn,WindDirectionDegrees,WindSpeedMPH,WindSpeedGustMPH,Humidity,HourlyPrecipIn" -force -encoding "UTF8"

#Open all csv files get-content and add it to the yearly file
$Files = dir -Path "C:\Users\Klaus\Desktop\TO PLANET\WeatherStation\FilterTest" -Filter "*.csv"

#Filter in Action
$Files | ForEach-Object `
{
        Get-Content -Path $_.Name -Encoding "UTF8" | Filter-Header | Add-Content -path $YearlyFileName -Encoding "UTF8"
}
  • Suchen Sie die letzten 2000 Systemereignisse des Eventlogs, die vom Typ “Error” sind

    # PowerShell script to find Error messages in the System eventlog.
    Get-EventLog system -newest 2000 | where {$_.entryType -match "Error"}
    
  • Sie schreiben ein Powershell-Skript, welches eine eigene Ereignisquelle im Eventlog schafft und darunter seine Ereignisse schreibt.

    ## Step 1 - PowerShell Script to create eventlog source by David Stone
    Clear-Host
    if (!(test-path ` HKLM:\SYSTEM\CurrentControlSet\Services\Eventlog\Application\SampleApp )) `
    {new-eventlog -logname Application -source SampleApp `
    -ErrorAction SilentlyContinue}
    
    ## Step 2 - Create a 'Job start' entry in your event log
    $startTime = Get-date
    $startLog = 'Sample job started at ' +$startTime+ ' local time'
    write-eventlog -LogName Application -Message $startLog -Source SampleApp `
    -id 1 -entrytype Information -Category 0
    
    ## Step 3 - A production script would have a payload here.
    
    ## Step 4 - Write errors during processing (typically part of a if statement)
    write-eventLog -LogName Application -Message 'Message content' `
    -Source SampleApp -id 100 -entrytype Warning -category 0
    
    ## Step 5 - Write end of process entry in your event log
    $endTime = Get-date
    $endLog = 'Sample job ended at ' +$endTime+ ' local time'
    write-eventlog -LogName Application -Message $endLog -Source SampleApp `
    -id 9 -entrytype Information -category 0
    
  • Schreiben Sie die Einträge der obigen Quelle in eine CSV-Datei. Es soll nur die jeweils letzte Stunde eingetragen werden

    ## Step 6 - Write the entries to a csv file
    Clear-Host
    $logtime=[DateTime]::Now.AddHours(-1)
    $CSVPath = "C:\SSource.csv"
    Get-EventLog -LogName application -Source 'SampleApp' `
    -EntryType warning -After $logtime `
    | select eventid, machinename, entrytype, source, message, timegenerated `
    | Export-Csv $CSVPath -NoTypeInformation
    
  • A Real-life Example of Select-String

    My practical problem was that I wanted to search for instances a particular string in a directory with hundreds of file. If a file had duplicate entries, then I needed to know.

    The PowerShell problem is how to create a stream of the files, then compare each file with my string value. In the output I needed to know the filename.

    To solve the problem, I employed four main commands, which you can see in the following script:

        Get-ChildItem - recurse
        foreach (loop) {what to do block}
    if (test) {output block}
    select-String -pattern to match my string value.
    
    # A real-life example of PowerShell's Select-String
    $i=0
    $File = Get-ChildItem "C:\html" -include *.html -recurse
    $StringVid = "msbuild"
    foreach ($Entry in $File) {
       $List = select-string -pattern $StringVid $Entry
              if ($List.LongLength -gt 1) {
              "{0,-8} {1,-4} {2,18}" -f
              "Files ", $List.LongLength, $Entry.FullName;
              $i++
              }
    }
    
  • Namensauflösung einer IP-Range

    Die Programmfunktionalität wird mit Hilfe von 2 Funktionen realisiert. Get-ComputerNameByIP zeigt die Verwendung von Fehlerbehandlungscode, Check-Online zeigt die Verwendung von Hintergrundprozessen.

    Als Speicher für die IP-Adressen und Hostnamen wird die Datenstruktur eines Hashes verwendet,

    <#
    .SYNOPSIS
    Gets a computer name
    .DESCRIPTION
    Resolve a computer name using an IP address
    .PARAMETER <paramName>
    $IPAddress
    .EXAMPLE
    Get-ComputerNameByIP "192.168.1.1"
    .AUTHOR
    G.W. Scheppink
    #>
    
    function Get-ComputerNameByIP {
                    param(
                            $IPAddress = $null
                    )
    
                    begin { }
    
                    process {
                            if ($IPAddress -and $_) {
                                    Throw "Please use either pipeline or input parameter"
                                    break
                            } elseif ($IPAddress) {
                                    ([System.Net.Dns]::GetHostbyAddress($IPAddress))
                            } elseif ($_) {
                                    trap [Exception] {
                                            write-warning $_.Exception.Message
                                            continue;
                                    }
                                    [System.Net.Dns]::GetHostbyAddress($_)
                            } else {
                                    $IPAddress = Read-Host "Please supply the IP Address"
                                    [System.Net.Dns]::GetHostbyAddress($IPAddress)
                            }
                    }
    
                    end { }
    
            } # End function
    
            function Check-Online {
                    param(
                            $computername
                    )
    
                    test-connection -count 1 -ComputerName $computername -TimeToLive 5 -asJob |
                    Wait-Job |
                    Receive-Job |
                    Where-Object { $_.StatusCode -eq 0 } |
                    Select-Object -ExpandProperty Address StatusCode
            }
    
            # This code pings an IP segment from 192.168.1.1 to 192.168.1.254 and returns only those IPs that respond.
            CLS
    
            $ip_name = @{}
            $Start = Get-Date
            $ips = 1..254 | ForEach-Object { "192.168.0.$_" }
            $online = Check-Online -computername $ips
            $online
    
            foreach ($PC in $online) {
                    $pcname =  Get-ComputerNameByIP $PC
                    $ip_name+=@{$PC=$pcname.HostName}
            }
    
            $End = Get-Date
            Write-Host "`nStarted at: " $Start
            Write-Host "Ended at: " $End
    
            $ip_name
    
            #umständliches Schreiben der key-value-Paare aus einem Hash heraus
            $ip_name.GetEnumerator() | Sort-Object Name |
            ForEach-Object {"{0} , {1}" -f $_.Name,$_.Value} |
            Add-Content C:\temp\log.csv`
    
  • Laptop oder Desktop

    Sie sind die IT-Leiter einer kleinen mittelständischen Firma. Sie müssen Inventur machen und Sie brauchen dazu die Anzahl der zur Zeit sich im Netz befindlichen Laptop-und Desktop-Computer in ihrer Firma.

    Following is the full script.
    
    <#
    .Synopsis
    
       helper function used by Get-HardwareType
    
    .EXAMPLE
    
       Example of how to use this cmdlet
    #>
    function Is-Laptop {
    
    [CmdletBinding()]
    [OutputType([boolean])]
    
            param
            (
            [Parameter(Mandatory=$true)]
            [string]        $strHostName
            )
    
            $blnResult = $false
            $query = "select __SERVER,ChassisTypes from Win32_SystemEnclosure"
    
    
                    $objWMI = Get-WmiObject -ComputerName $strHostName -Query $query -ErrorAction Stop
    
                    switch ($objWMI.ChassisTypes) {
    
                            9  {$blnResult = $true} # Laptop
                            10 {$blnResult = $true} # Notebook
                            12 {$blnResult = $true} # Docking Station
                            14 {$blnResult = $true} # Sub Notebook
                            default {}
                      }
                      return $blnResult
    
    } # end function
    
    <#
    
    .Synopsis
      function to determine chassis type using a WMI query
    
    .DESCRIPTION
       function to determine chassis type using a WMI query
    
    .EXAMPLE
       "pc01","pc02","pc03" | Get-HardwareType
    #>
    function Get-HardwareType {
    
    [CmdletBinding()]
    [OutputType([psobject])]
    
    Param
    (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    $strHostName
    )
    
    process {
    
            try {
    
                    $objHostName = [system.net.dns]::GetHostByName($strHostName)
    
                    $query = "select __SERVER,ChassisTypes from Win32_SystemEnclosure"
    
                            if (Test-Connection -ComputerName $objHostName.HostName -count 1 -erroraction silentlycontinue) {
    
                                    try {
    
                                            $objResult = New-Object -TypeName psobject -Property @{HostName=$objHostName.HostName;IsLaptop=(Is-Laptop -strHostName $objHostName.HostName)}
    
                                            return $objResult
    
                                    }
    
                                    catch {
    
                                            "Error trying to query $($objHostName.HostName)"
    
                                    }
    
                       }
    
                       else {
    
                                    write-host "error connecting to $($objHostName.HostName)"
    
                       }
    
            }
    
            catch {
    
                    write-host "Unable to resolve DNS address for $strHostName"
    
            }
    
      }
    
    } # end function
    
    
    $laptopCount = 0
    $desktopCount = 0
    
    $searcher = new-object directoryservices.directorysearcher([ADSI]"","(&(objectcategory=computer)(!operatingsystem=*server*))")
    
    [void]$searcher.PropertiesToLoad.Add("cn")
    $arrMachineName = $searcher.findall() | %{$_.properties.cn}
    
    $result = $arrMachineName | Get-HardwareType
    $result
    
    $result | ForEach-Object {if ($_.islaptop) {$laptopCount++} else {$desktopCount++}}
    
    "Laptop Total: $laptopCount"
    "Desktop Total: $desktopCount"
    
    ## beim Lesen aus Textdatei
    #$result = import-csv C:\temp\laptop_desktop.ps1 | Group-Object {$_.chassis} -noelement
    #$result = import-csv C:\temp\laptop_desktop.ps1 | Group-Object -property chassis -noelement
    
    #$result