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:
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
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
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!"
}
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:
#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