All posts in Powershell

Hallo zusammen,

in dem heutigen Howto zeige ich euch ein kleines Powershell Skript, wie Ihr Logdateien in Realtime monitoren könnt.
Folgenden Zeilen im Skript sollten angepasst werden, über diese Variablen könnt Ihr das Monitoring steuern.

Im Header des Skripts habe ich den Ablauf dokumentiert, sollten noch Fragen aufkommen, Ihr wisst wie Ihr mich erreichen könnt.

## $EmailPasswortFile = "D:\PowershellScripte\MailPasswort.txt"
$LogFiletoCheck = "D:\PowershellScripte\MyLogFiles.txt"
$ScriptSleepTimeOut = 10 ## 10 Sekunden Pause in der Skript Schleife
$ScriptLoopTime = 5 ## 5 Minuten Skriptlaufzeit
$EventCheckCount = 15 ## Überprüft das Dienstprotokoll nach der Anzahl der Ereignisse, hier Maximal 15 Einträge
$EventTimeRange = 30 ## Zeitspanne für die Anzahl der Ereignisse, wenn mehr als 15 Einträge in 30 Minuten geschrieben werden, mach irgendwas (z.B. E-Mail versenden)
#########################################################################################################
##
## Name: Log Datei überwachung, Ergebnisse ins Dienstprotokoll schreiben                            
## Ersteller: Helmut Thurnhofer                    
## Erstellungsdatum: 05.01.2016                                                             
## Version: 1.0
##
#######################################################
## Skriptbeschreibung und Vorbereitung auf dem Server:
#######################################################
##
## Um mit dem Skript arbeiten zu können müssen ein paar Vorbereitungen auf dem Server getroffen werden.
## Zum einem muss die ExecutionPolicy für den auszuführenden Benutzer gesetzt werden und zum zweiten wird in der Ereignisanzeige
## ein neues Dienstprotokoll angelegt. (Zu finden unter Anwendungs- und Dienstprotokoll)
##
## Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force 
## (Die Powershell wird keine Skripte ausführen, die aus dem Internet stammen – Für unsere Aufgabe beste Wahl.)
##
## Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force 
## (Die Powershell ignoriert die digitale Signatur, fragt aber nach, ob ein Skript, das aus dem Internet stammt, ausgeführt werden soll.)
##
###################################################
## Dienstprotokoll anlegen mit folgenden Befehlen:
###################################################
##    
## New-EventLog -LogName MeinServerLog -Source Error,Fatal,Warning,Information
## Limit-EventLog -LogName MeinServerLog -MaximumSize 10485760 -OverflowAction OverwriteAsNeeded
##
## -MaximumSize 524288 = 512KB
## -MaximumSize 1048576 = 1024KB = 1MB
## -MaximumSize 10485760 = 10240KB = 10MB
## -MaximumSize 20971520 = 20480KB = 20MB
##
################################################################
## Testeinträge in das neu erstellte Dienstprotokoll schreiben:
################################################################
##
## Write-EventLog -LogName MeinServerLog -Source Information -EntryType Information -EventId 1000 -Message "Information über die PowerShell"
## Write-EventLog -LogName MeinServerLog -Source Warning -EntryType Warning -EventId 2000 -Message "Warning über die PowerShell"
## Write-EventLog -LogName MeinServerLog -Source Error -EntryType Error -EventId 3000 -Message "Error über die PowerShell"
## Write-EventLog -LogName MeinServerLog -Source Fatal -EntryType Error -EventId 4000 -Message "Fatal über die PowerShell"
##
## Für die Events wurde eigene EventIDs verwendet, Information=1000, Warnungen=2000, Error=3000, Fatal=4000
##
#############################################
## Testeinträge im Dienstprotokoll abfragen:
#############################################
##
## Get-EventLog -LogName MeinServerLog -InstanceId 3000,4000 -Newest 20
##
## $DateNow = Get-Date
## $Time30Minutes = (Get-Date).AddMinutes(-30)
## Get-EventLog -LogName MeinServerLog -EntryType Error -Before $DateNow -After $Time30Minutes
##
## Get-EventLog -LogName MeinServerLog -Source Fatal,Error
## Get-EventLog -List
##
##############################################################################################################
## Um das ganze Simulieren zu können, wurde eine leere Log Datei erstellt und mit folgenden Einträgen gefüllt.
## Die Einträge wurden Zeitversetzt über eine zweite Powershell Sitzung ausgeführt.
##############################################################################################################
##
## $Date = Get-Date
## $DateTime = $Date.ToString("yyyy-MM-dd HH:mm:ss")
## Add-Content "D:\PowershellScripte\MyLogFiles.txt" -Value "$DateTime - FATAL: 0x80070490: EvaluateApplicability failed in CCbs::EvaluateApplicability"
##
## $Date = Get-Date
## $DateTime = $Date.ToString("yyyy-MM-dd HH:mm:ss")
## Add-Content "D:\PowershellScripte\MyLogFiles.txt" -Value "$DateTime - ERROR: 0x80070432: Forced install timer expired for AUInstallType = 4"
##
## $Date = Get-Date
## $DateTime = $Date.ToString("yyyy-MM-dd HH:mm:ss")
## Add-Content "D:\PowershellScripte\MyLogFiles.txt" -Value "$DateTime - Information: 0x80000000: Successfully wrote event for AU health state:0"
## 
## $Date = Get-Date
## $DateTime = $Date.ToString("yyyy-MM-dd HH:mm:ss")
## Add-Content "D:\PowershellScripte\MyLogFiles.txt" -Value "$DateTime - Warning: 0x80202000: Warning event for AU health state were 3"
##
######################################################################
## Bitte diese Zeilen vor dem ersten Lauf im Skript ausführen, 
## Hier wird das E-Mail Benutzer Passwort als String in einen Textdatei geschrieben.
## Diese Textdatei wird für den späteren E-Mail versandt benötigt.
######################################################################
##
## (Get-Credential).Password | ConvertFrom-SecureString > $EmailPasswortFile
##
#########################################################################################################
Clear-Host

## Basisparameter für das Skript
##
## $EmailPasswortFile = "D:\PowershellScripte\MailPasswort.txt"
$LogFiletoCheck = "D:\PowershellScripte\MyLogFiles.txt"
$ScriptSleepTimeOut = 10 ## 10 Sekunden Pause in der Skript Schleife
$ScriptLoopTime = 5 ## 5 Minuten Skriptlaufzeit
$EventCheckCount = 15 ## Überprüft das Dienstprotokoll nach der Anzahl der Ereignisse, hier Maximal 15 Einträge
$EventTimeRange = 30 ## Zeitspanne für die Anzahl der Ereignisse, wenn mehr als 15 Einträge in 30 Minuten geschrieben werden, mach irgendwas (E-Mail versenden)
##
#########################################################################################################


## Basis E-Mail Server Konfiguration
##
## $ServerName = "$env:COMPUTERNAME.$env:USERDOMAIN"
## $KundenName = "Musterkunde Deutschland GmbH"
## $SMTPServer = "smtp.domain.de"
## $SMTPUserName = "Benutzername"
## Bitte diese Skriptzeile vorab ausführen damit die EmailPasswort datei erstellt wird.
##
## (Get-Credential).Password | ConvertFrom-SecureString > $EmailPasswortFile
## $SMTPUserPwd = Get-Content -Path $MailPasswortFile | ConvertTo-SecureString
## $Cred = New-Object System.Management.Automation.PSCredential $SMTPUserName, $SMTPUserPwd
##
## Basisinformationen für den E-Mail versandt.
##
## $EmailTo = empfaenger@domain.de
## $EmailFrom = absender@domain.de
## $EmailSubject = "Es wurde beim `"$KundenName`" mehr als 15 Fatal/Error Einträge in den Logs gefunden. Bitte Server: `"$ServerName`" überprüfen!"
## $EmailBody ist weiter unten im Skript definiert, da hier die Auswertung der Variaben benötigt werden.
#########################################################################################################


$LoopStartTime = Get-Date
$LoopStartTimeFormatted = $LoopStartTime.ToString("dd.MM.yyyy HH:mm:ss")

$LoopEndTime = $LoopStartTime.AddMinutes($ScriptLoopTime)
$LoopEndTimeFormatted = $LoopEndTime.ToString("dd.MM.yyyy HH:mm:ss")
## $LoopEndTime = $LoopStartTime.AddHours($ScriptLoopTime)
## $LoopEndTimeFormated = $LoopEndTime.ToString("dd.MM.yyyy HH:mm:ss")

Write-Host "`nRealtime LogFile Monitoring wurde gestartet um: $LoopStartTimeFormatted" -ForegroundColor Gray
write-host "Realtime LogFile Monitoring wird beendet um: $LoopEndTimeFormatted`n" -ForegroundColor Gray
#########################################################################################################

## Alle 10 Sekunden wird die Schleife wiederholt, bei einem Treffer im Log wird ein Ereigniseintrag geschrieben
## Wenn mehr als 15 Einträge in 30 Minuten geschrieben werden, wird eine E-Mail Versand.
## Skript Idee -- http://sion-it.co.uk/tech/powershell/loop-until-a-certain-time

Do { 
     ## Hier wird pro Schleifendurchlauf die Aktuelle Zeit geholt und neu gesetzt
     ##
     $LoopTimeNow = Get-Date
     $LoopTimeNowFormatted = $LoopTimeNow.ToString("dd.MM.yyyy HH:mm:ss")

     ## Diese Zeitangabe wird für die Suche in der Log Datei benötigt, wenn hier Einträge älter/gleich Suchzeit ist.
     ## Wird ein neuer Dienstprotokoll Eintrag geschrieben, diese Zeit sollte mit der Skriptpause übereinstimmen,
     ## ansonsten werden hier wo wöglich neue Einträge in der Log nicht gefunden, das Sie aus der Zeitrange fallen.
     ##
     $SearchTime = (Get-Date).AddSeconds(-$ScriptSleepTimeOut)
     $SearchTimeInLog = $SearchTime.ToString("yyyy-MM-dd HH:mm:ss")

     If ($LoopTimeNow -ge $LoopEndTime) {
        Write-host "Endzeit: `"$LoopEndTimeFormatted`" ist erreicht, Skript wird im nächsten Durchgang beenden."
 
     } Else {
        
        ## Überprüft die Einträge in der Log Datei, sollte was gefunden werden, wird es an die ForEach Schleife übergeben und in das Dienstprotokoll geschrieben.
        ##
        [string[]]$FatalMessages = Get-Content $LogFiletoCheck | Where-Object {($_ -ge $SearchTimeInLog) -and $_ -match "FATAL"}
        [string[]]$ErrorMessages = Get-Content $LogFiletoCheck | Where-Object {($_ -ge $SearchTimeInLog) -and $_ -match "ERROR"}
        [string[]]$WarningMessages = Get-Content $LogFiletoCheck | Where-Object {($_ -ge $SearchTimeInLog) -and $_ -match "Warning"}

        ForEach ($FatalMessage in $FatalMessages) {
        Write-EventLog -LogName enaioServerLog -Source Fatal -EntryType Error -EventId 4000 -Message "$FatalMessage"
        Write-Host "Ereigniseintrag `"$FatalMessage`" wurde erstellt." -ForegroundColor DarkRed     
        }

        ForEach ($ErrorMessage in $ErrorMessages) {
        Write-EventLog -LogName enaioServerLog -Source Error -EntryType Error -EventId 3000 -Message "$ErrorMessage"
        Write-Host "Ereigniseintrag `"$ErrorMessage`" wurde erstellt." -ForegroundColor DarkRed     
        }

        ForEach ($WarningMessage in $WarningMessages) {
        Write-EventLog -LogName enaioServerLog -Source Warning -EntryType Warning -EventId 2000 -Message "$WarningMessage"
        Write-Host "Ereigniseintrag `"$WarningMessage`" wurde erstellt." -ForegroundColor DarkYellow     
        }
            
            ## Überprüfe das Dienstprotokoll, wenn mehr als 15 Einträge in 30 Minuten geschrieben wurden, wird eine E-Mail an den Administrator versendet.
            ##
            $Count = $EventCheckCount
            $DateNow = Get-Date
            $Time30Minutes = (Get-Date).AddMinutes(-$EventTimeRange)
            $EventDate = $Time30Minutes.ToString("yyyy-MM-dd HH:mm:ss")
            $EventCount = (Get-EventLog -LogName enaioServerLog -InstanceId 3000,4000 -Before $DateNow -After $Time30Minutes).Count
            ## $EmailBody = "In den letzten 30 Minuten sind mehr als $Count (Gesamt: $EventCount) Fatal oder Error Ereigniseinträge geschrieben worden."
                    
            If($EventCount -ge $Count) {
                   
                Write-Host "`nIn den letzten 30 Minuten sind mehr als $Count (Gesamt: $EventCount) Fatal oder Error Ereigniseinträge geschrieben worden." -ForegroundColor DarkRed
                Write-Host "E-Mail wird versendet, da mehr als $Count (Gesamt: $EventCount) Fatal oder Error Ereigniseinträge geschrieben worden sind." -ForegroundColor DarkRed
                ## Aktion einfügen wie z.B. Mail versandt
                ##
                ## Send-MailMessage -Credential $Cred -SmtpServer $SMTPServer -To $EmailTo -From $EmailFrom -Subject $EmailSubject -Body $EmailBody -Encoding ([System.Text.Encoding]::UTF8)
            
            } Else {

                Write-Host "`nIn den letzten 30 Minuten sind weniger als $Count (Gesamt: $EventCount) Fatal oder Error Ereigniseinträge geschrieben worden." -ForegroundColor DarkGreen
                Write-Host "E-Mail wird nicht versendet, da weniger als $Count (Gesamt: $EventCount) Fatal oder Error Ereigniseinträge geschrieben worden sind." -ForegroundColor DarkGreen
            }

        ## Statusmeldung, wie lange das Skript noch ausgeführt wird
        ##
        Write-Host "Skript wird noch nicht beendet, es läuft noch bis `"$LoopEndTimeFormatted`"" -ForegroundColor Gray
     }

 ## Skriptpause bis die Schleife wiederholt wird
 ##
 Start-Sleep -Seconds $ScriptSleepTimeOut

}
## Skript wird nach Erreichen der Angegeben Zeit beendet
##
Until ($LoopTimeNow -ge $LoopEndTime)

Wie immer freue ich mich über Kommentare und Anregungen.

Viele Grüße
Helmut

Hallo zusammen,

in dem heutigen Howto zeige ich euch ein kleines Skript, wie Ihr eure Powershell Umgebung auf allen Computern/Server gleich setzen könnt.

Powershell_Konsole

 

 

 

 

 

Powershell_Konsole_2

 

 

 

 

 

Bitte vor der Skript Ausführung eure ExecutionPolicy setzen

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force

Damit Powershell immer ein Startverzeichnis hat, bitte die passende Variable im Skript setzen

$StartFolder="C:\ oder D:\DeinVerzeichnis"

Und hier das Skript

#######################################################################################
## Skript:  Powershell Profil Datei anlegen
## Name:    Helmut Thurnhofer
## Datum:   03.01.2016
## Version: 1.0
##
## Powershell Konsolen Anpassung
## https://tobivnext.wordpress.com/2012/03/07/powershell-konsoleneigenschaften-anpassen/
##
## Bitte vor Skriptausführung ExecutionPolicy setzen
## Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force
##
## Bitte auch einen passenden Startverzeichnis für Powershell setzen 
## $StartFolder="C:\ oder D:\DeinVerzeichnis"
#######################################################################################
 
## Skript Variablen definieren ########################################################
$DateTime = (Get-Date -Format g)
$ProfileFile = $PROFILE.CurrentUserAllHosts
$SplitProfileFile = Split-Path -Path $ProfileFile -Leaf -Resolve
$SplitProfilePath = Split-Path -Path $ProfileFile -Parent -Resolve
$BackupProfileFile = $SplitProfilePath + "\" + "profile.bak"
$CheckProfileFile = Test-Path -PathType Leaf $ProfileFile
$StartFolder="D:\PowershellScripte"
#######################################################################################
 
## Startverzeichnis anlegen wenn noch nicht vorhanden #################################
If (!(Test-Path -Path $StartFolder)){
 
     New-Item -Type Directory -Path $StartFolder
     Write-Host "Der Ordner $StartFolder wurde angelegt" -ForegroundColor Green
} Else {
    Write-Host "Der Ordner $StartFolder existiert bereits." -ForegroundColor Yellow
}
#######################################################################################
 
 
## Überprüfe ob alte profil.ps1 Datei vorhanden ist, wenn ja, wird diese umbenannt und neu angelegt.
If($CheckProfileFile -eq $true) {
    Rename-Item -Path $ProfileFile -NewName $BackupProfileFile
    Write-Host "Powershell Profil Datei (`"$BackupProfileFile`") wurde umbenannt!`n" -ForegroundColor Yellow
 
    New-Item -ItemType File -Force $ProfileFile
    Write-Host "Powershell Profil Datei (`"$ProfileFile`") wurde neu angelegt!`n" -ForegroundColor Green
} Else {
    New-Item -ItemType File -Force $ProfileFile
    Write-Host "Powershell Profil Datei (`"$ProfileFile`") wurde neu angelegt!`n" -ForegroundColor Green
}
#######################################################################################


## Schreibe Inhalt in die profile.ps1 Datei
Add-Content $ProfileFile -Value "#####################################################################################"
Add-Content $ProfileFile -Value "## Name: Windows PowerShell Profil"
Add-Content $ProfileFile -Value "## Ersteller: $env:USERNAME"
Add-Content $ProfileFile -Value "## Erstellungsdatum: $DateTime"
Add-Content $ProfileFile -Value "## Version: 1.0"
Add-Content $ProfileFile -Value "#####################################################################################"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Skript von http://www.zerrouki.com/powershell-profile-example"
Add-Content $ProfileFile -Value "`$IPAddress=@(Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {`$_.DefaultIpGateway})[0].IPAddress[0]"
Add-Content $ProfileFile -Value "`$PSVersion=(`$PSVersionTable.PSVersion).ToString()"
Add-Content $ProfileFile -Value "Clear-Host"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "Write-Host `"``r``n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::`" -ForegroundColor Yellow"
Add-Content $ProfileFile -Value "Write-Host `"::`" -ForegroundColor Yellow -nonewline; Write-Host `"  ComputerName: `$(`$env:COMPUTERNAME)`";"
Add-Content $ProfileFile -Value "Write-Host `"::`" -ForegroundColor Yellow -nonewline; Write-Host `"  IP-Adresse:   `$IPAddress`";"
Add-Content $ProfileFile -Value "Write-Host `"::`" -ForegroundColor Yellow -nonewline; Write-Host `"  UserName:     `$env:UserDomain\`$env:UserName`";"
Add-Content $ProfileFile -Value "Write-Host `"::`" -ForegroundColor Yellow -nonewline; Write-Host `"  Powershell:   `$PSVersion`" -NoNewline;"
Add-Content $ProfileFile -Value "Write-Host `"``r``n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::`" -ForegroundColor Yellow"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "`$AllDisk = @()"
Add-Content $ProfileFile -Value "Get-WmiObject Win32_LogicalDisk -filter `"DriveType='3'`" | ForEach-Object {"
Add-Content $ProfileFile -Value "   `$AllDisk += @(`$_ | Select @{n=`"Name`";e={`$_.Caption}},"
Add-Content $ProfileFile -Value "   @{n=`"Bezeichnung`";e={`$_.VolumeName}},"
Add-Content $ProfileFile -Value "   @{n=`"Groesse (GB)`";e={`"{0:N2}`" -f (`$_.Size/1GB)}},"
Add-Content $ProfileFile -Value "   @{n=`"Belegt (GB)`";e={`"{0:N2}`" -f ((`$_.Size/1GB) - (`$_.FreeSpace/1GB))}},"
Add-Content $ProfileFile -Value "   @{n=`"Frei (GB)`";e={`"{0:N2}`" -f (`$_.FreeSpace/1GB)}},"
Add-Content $ProfileFile -Value "   @{n=`"Frei (%)`";e={if(`$_.Size) {`"{0:N2}`" -f ((`$_.FreeSpace/1GB) / (`$_.Size/1GB) * 100 )} else {`"NAN`"} }})"
Add-Content $ProfileFile -Value "}"
Add-Content $ProfileFile -Value "`$AllDisk | Format-Table -AutoSize | Out-String"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Globale Standardvariablen setzen"
Add-Content $ProfileFile -Value "`$ErrorActionPreference = `"Continue`""
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Setzen das Startverzeichnis"
Add-Content $ProfileFile -Value "Set-Location -Path $StartFolder"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Angepasster Powershell Titel"
Add-Content $ProfileFile -Value "`$a = (Get-Host).UI.RawUI"
Add-Content $ProfileFile -Value "`$a.WindowTitle = `"HTDOM - Powershell`""
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Angepasster PowerShell Prompt"
Add-Content $ProfileFile -Value "function prompt {"
Add-Content $ProfileFile -Value "`$msg = `"HTDOM `$(`$ExecutionContext.SessionState.Path.CurrentLocation)`$(`'>`' * (`$NestedPromptLevel + 1))`""
Add-Content $ProfileFile -Value "Write-Host -ForegroundColor Yellow -NoNewLine `$msg; `" `""
Add-Content $ProfileFile -Value "`}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "## Setzt bestimmte Alias und Funktionen"
Add-Content $ProfileFile -Value "function pss{Set-Location -Path $StartFolder}"
Add-Content $ProfileFile -Value "function c{Set-Location -Path C:\}"
Add-Content $ProfileFile -Value "function d{Set-Location -Path D:\}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "function ..{cd ..}"
Add-Content $ProfileFile -Value "function ...{cd ..\..}"
Add-Content $ProfileFile -Value "function ....{cd ..\..\..}"
Add-Content $ProfileFile -Value "function .....{cd ..\..\..\..}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "function ws{Set-Location -Path C:\Windows\System32}"
Add-Content $ProfileFile -Value "function npp{notepad `$PROFILE.CurrentUserAllHosts}"
Add-Content $ProfileFile -Value "function np{Start-Process -FilePath `"C:\Program Files (x86)\Notepad++\notepad++.exe`" -Verb RunAs}"
Add-Content $ProfileFile -Value "function ise{Start-Process -FilePath `"C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe`" -Verb RunAs}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "function kb(`$id){Start-Process -FilePath `"http://support.microsoft.com/kb/`$id`"}"
Add-Content $ProfileFile -Value "function mwst(`$betrag, `$satz = 19) {`$betrag / 100 * `$satz}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "function applog{Get-EventLog -LogName Application -Newest 50}"
Add-Content $ProfileFile -Value "function syslog {Get-EventLog -LogName System -Newest 50}"
Add-Content $ProfileFile -Value ""
Add-Content $ProfileFile -Value "function gco(`$Cmdlet){Get-Command `$Cmdlet -CommandType Cmdlet}"
Add-Content $ProfileFile -Value "function about{Get-Help about_* | Select name, synopsis | Format-Table -AutoSize}"
Add-Content $ProfileFile -Value "function module{Get-Module -ListAvailable | Where-Object {`$_.Path -like `"`$PSHOME*`"}}"
#######################################################################################

## Profil in der aktuellen Sitzung laden
. $PROFILE.CurrentUserAllHosts
#######################################################################################

## Erstelle Regkeys für HKEY_CURRENT_USER\Console
$RegPath1="HKCU:\Console"
Set-Location -Path $RegPath1

## Konsolenfarben setzen
New-ItemProperty . ColorTable00 -type DWORD -value 0x00222827 -Force
New-ItemProperty . ColorTable03 -type DWORD -value 0x00141817 -Force
New-ItemProperty . ColorTable07 -type DWORD -value 0x00f2f8f8 -Force
New-ItemProperty . ColorTable09 -type DWORD -value 0x00efd966 -Force
New-ItemProperty . ColorTable10 -type DWORD -value 0x002ee2a6 -Force
New-ItemProperty . ColorTable12 -type DWORD -value 0x007226f9 -Force
New-ItemProperty . ColorTable14 -type DWORD -value 0x0074dbe6 -Force

## Schriftart und zusätzlich Optionen setzen
New-ItemProperty . CurrentPage -type DWORD -value 0x00000003 -Force
New-ItemProperty . CursorSize -type DWORD -value 0x00000019 -Force
New-ItemProperty . EnableColorSelection -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKey -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKeyCustom -type DWORD -value 0x00000000 -Force
New-ItemProperty . FaceName -type STRING -value "Consolas" -Force
New-ItemProperty . FontFamily -type DWORD -value 0x00000036 -Force
New-ItemProperty . FontSize -type DWORD -value 0x000e0000 -Force
New-ItemProperty . FontWeight -type DWORD -value 0x00000190 -Force
New-ItemProperty . FullScreen -type DWORD -value 0x00000000 -Force
New-ItemProperty . HistoryBufferSize -type DWORD -value 0x00000032 -Force
New-ItemProperty . HistoryNoDup -type DWORD -value 0x00000000 -Force
New-ItemProperty . InsertMode -type DWORD -value 0x00000001 -Force
New-ItemProperty . LoadConIme -type DWORD -value 0x00000001 -Force
New-ItemProperty . NumberOfHistoryBuffers -type DWORD -value 0x00000004 -Force
New-ItemProperty . PopupColors -type DWORD -value 0x000000f5 -Force
New-ItemProperty . QuickEdit -type DWORD -value 0x00000001 -Force
New-ItemProperty . ScreenBufferSize -type DWORD -value 0x270f00c8 -Force
New-ItemProperty . ScreenColors -type DWORD -value 0x0000000f -Force
New-ItemProperty . TrimLeadingZeros -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowSize -type DWORD -value 0x003600c8 -Force
New-ItemProperty . WordDelimiters -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowPosition -type DWORD -value 0x003c00dc -Force
#######################################################################################

## Erstelle Regkeys für HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
$RegPath2="HKCU:\Console\%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe"
$CheckRegKey2 = Test-Path -Path $RegPath2

if ($CheckRegKey2 -eq $true) {
    Clear-Host
    Remove-Item -Path $RegPath2 -Recurse -Force
    Write-Host "`nRegistrieschlüssel ist vorhanden und wird gelöscht!`n" -ForegroundColor Yellow
    New-Item -Path "HKCU:\Console" -Name "%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe" -Force
    Write-Host "`nRegistrieschlüssel ist nicht vorhanden und wird angelegt.`n" -ForegroundColor Green
} else {
    Clear-Host
    New-Item -Path "HKCU:\Console" -Name "%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe" -Force
    Write-Host "`nRegistrieschlüssel ist nicht vorhanden und wird angelegt.`n" -ForegroundColor Green
}

Set-Location -Path $RegPath2

## Konsolenfarben setzen
New-ItemProperty . ColorTable00 -type DWORD -value 0x00222827 -Force
New-ItemProperty . ColorTable03 -type DWORD -value 0x00141817 -Force
New-ItemProperty . ColorTable07 -type DWORD -value 0x00f2f8f8 -Force
New-ItemProperty . ColorTable09 -type DWORD -value 0x00efd966 -Force
New-ItemProperty . ColorTable10 -type DWORD -value 0x002ee2a6 -Force
New-ItemProperty . ColorTable12 -type DWORD -value 0x007226f9 -Force
New-ItemProperty . ColorTable14 -type DWORD -value 0x0074dbe6 -Force

## Schriftart und zusätzlich Optionen setzen
New-ItemProperty . CurrentPage -type DWORD -value 0x00000003 -Force
New-ItemProperty . CursorSize -type DWORD -value 0x00000019 -Force
New-ItemProperty . EnableColorSelection -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKey -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKeyCustom -type DWORD -value 0x00000000 -Force
New-ItemProperty . FaceName -type STRING -value "Consolas" -Force
New-ItemProperty . FontFamily -type DWORD -value 0x00000036 -Force
New-ItemProperty . FontSize -type DWORD -value 0x000e0000 -Force
New-ItemProperty . FontWeight -type DWORD -value 0x00000190 -Force
New-ItemProperty . FullScreen -type DWORD -value 0x00000000 -Force
New-ItemProperty . HistoryBufferSize -type DWORD -value 0x00000032 -Force
New-ItemProperty . HistoryNoDup -type DWORD -value 0x00000000 -Force
New-ItemProperty . InsertMode -type DWORD -value 0x00000001 -Force
New-ItemProperty . LoadConIme -type DWORD -value 0x00000001 -Force
New-ItemProperty . NumberOfHistoryBuffers -type DWORD -value 0x00000004 -Force
New-ItemProperty . PopupColors -type DWORD -value 0x000000f5 -Force
New-ItemProperty . QuickEdit -type DWORD -value 0x00000001 -Force
New-ItemProperty . ScreenBufferSize -type DWORD -value 0x270f00c8 -Force
New-ItemProperty . ScreenColors -type DWORD -value 0x0000000f -Force
New-ItemProperty . TrimLeadingZeros -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowSize -type DWORD -value 0x003600c8 -Force
New-ItemProperty . WordDelimiters -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowPosition -type DWORD -value 0x003c00dc -Force
#######################################################################################

## Kopiere Regkeys für HKEY_CURRENT_USER\Console\Windows PowerShell
$RegPath3="HKCU:\Console\Windows PowerShell"
$CheckRegKey3 = Test-Path -Path $RegPath3

if ($CheckRegKey3 -eq $true) {
    Clear-Host
    Remove-Item -Path $RegPath3 -Recurse -Force
    Write-Host "`nRegistrieschlüssel ist vorhanden und wird gelöscht!`n" -ForegroundColor Yellow
    New-Item -Path "HKCU:\Console" -Name "Windows PowerShell" -Force
    Write-Host "`nRegistrieschlüssel ist nicht vorhanden und wird angelegt.`n" -ForegroundColor Green
} else {
    Clear-Host
    New-Item -Path "HKCU:\Console" -Name "Windows PowerShell" -Force
    Write-Host "`nRegistrieschlüssel ist nicht vorhanden und wird angelegt.`n" -ForegroundColor Green
}

Set-Location -Path $RegPath3

## Konsolenfarben setzen
New-ItemProperty . ColorTable00 -type DWORD -value 0x00222827 -Force
New-ItemProperty . ColorTable03 -type DWORD -value 0x00141817 -Force
New-ItemProperty . ColorTable07 -type DWORD -value 0x00f2f8f8 -Force
New-ItemProperty . ColorTable09 -type DWORD -value 0x00efd966 -Force
New-ItemProperty . ColorTable10 -type DWORD -value 0x002ee2a6 -Force
New-ItemProperty . ColorTable12 -type DWORD -value 0x007226f9 -Force
New-ItemProperty . ColorTable14 -type DWORD -value 0x0074dbe6 -Force

## Schriftart und zusätzlich Optionen setzen
New-ItemProperty . CurrentPage -type DWORD -value 0x00000003 -Force
New-ItemProperty . CursorSize -type DWORD -value 0x00000019 -Force
New-ItemProperty . EnableColorSelection -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKey -type DWORD -value 0x00000000 -Force
New-ItemProperty . ExtendedEditKeyCustom -type DWORD -value 0x00000000 -Force
New-ItemProperty . FaceName -type STRING -value "Consolas" -Force
New-ItemProperty . FontFamily -type DWORD -value 0x00000036 -Force
New-ItemProperty . FontSize -type DWORD -value 0x000e0000 -Force
New-ItemProperty . FontWeight -type DWORD -value 0x00000190 -Force
New-ItemProperty . FullScreen -type DWORD -value 0x00000000 -Force
New-ItemProperty . HistoryBufferSize -type DWORD -value 0x00000032 -Force
New-ItemProperty . HistoryNoDup -type DWORD -value 0x00000000 -Force
New-ItemProperty . InsertMode -type DWORD -value 0x00000001 -Force
New-ItemProperty . LoadConIme -type DWORD -value 0x00000001 -Force
New-ItemProperty . NumberOfHistoryBuffers -type DWORD -value 0x00000004 -Force
New-ItemProperty . PopupColors -type DWORD -value 0x000000f5 -Force
New-ItemProperty . QuickEdit -type DWORD -value 0x00000001 -Force
New-ItemProperty . ScreenBufferSize -type DWORD -value 0x270f00c8 -Force
New-ItemProperty . ScreenColors -type DWORD -value 0x0000000f -Force
New-ItemProperty . TrimLeadingZeros -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowSize -type DWORD -value 0x003600c8 -Force
New-ItemProperty . WordDelimiters -type DWORD -value 0x00000000 -Force
New-ItemProperty . WindowPosition -type DWORD -value 0x003c00dc -Force
#######################################################################################

## Powershell Verknüpfung erstellen
$ComObj = New-Object -ComObject Wscript.Shell
$Shortcut = $ComObj.CreateShortcut("$env:USERPROFILE\Desktop\Powershell.lnk")
$ShortCut.TargetPath = "$PSHOME\powershell.exe"
$ShortCut.Hotkey = "CTRL+ALT+P"
$ShortCut.Save()
####################################################################################### 

Wie immer freue ich mich über Kommentare und Anregungen.

Viele Grüße
Helmut

Hallo zusammen,

in dem heutigen Howto zeige ich euch, wie Ihr SQLite mit Powershell nutzen könnt.
Um euch eine Alternative zu XML-Dateien aus meinem letzten Post vorzustellen, nutzen wir diesmal SQLite Datenbanken.

Für die XML-Dateien hatte ich mir eine Serverstruktur aufgebaut, die ich später abfragen konnte. Die gleiche Servestruktur werde ich nun in einer SQLite Datenbank abbilden, die wir wiederum später mit Powershell abfragen können.

Arbeitsdateien für das Howto

Um grundlegend mit SQLite Datenbanken zu arbeiten und die Datenbankstruktur anlegen, verwalten und ansehen zu können, benötigt man ein Management Tool.
Hierzu kann man folgende Software/Tools nutzen.

SQLite Database Browser
SQLite_Database_Browser

 

 

 

 

 
SQLite Manager (Firefox AddOn)
SQLite_Manager

 

 

 

 

 
Weitere Management Tools findet ihr bei SQLite.org –> http://www.sqlite.org/cvstrac/wiki?p=ManagementTools

Um überhaupt SQLite Datenbanken mit Powershell abfragen zu können, benötigt man die System.Data.SQLite Runtime bzw. die System.Data.SQLite.dll. Das passende Softwarepaket findet man auf folgender Webseite.

http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
http://system.data.sqlite.org/downloads/1.0.92.0/sqlite-netFx451-setup-bundle-x64-2013-1.0.92.0.exe

Nach der Installation findet man lokal folgende Struktur vor. Mit dieser Struktur werden wir im nachfolgenden Howto arbeiten.
FileStruktur

 

 

 

 

 

 
Um die Datenbank schnell mit Informationen füllen zu können, habe ich euch ein Excelsheet mit ein paar Demo Einträgen vorbereitet, dazu das passende VB Script für den Export in eine TXT Datei.
Nach dem Export der TXT Datei müssen noch ein paar Anpassungen gemacht werden, damit der Import sauber funktioniert.
Export_Excel

 

 

 

 

 
Export_Import_Datei

 

 

 

 

 
Datenbank_vorbereiten

 

 

 

 

 
Datenbank_vorbereiten2

 

 

 

 

 
Nachdem die Datenbank vorbereitet ist, können wir uns den Powershellabfragen widmen.

Auch ich habe mich vorab im Internet informiert, wie so eine Abfrage funktioniert und habe drei gute Ansätze gefunden, die ich euch in dem Post vorstelle.

Erste Beispiel:
Gefunden bei http://thescriptingfrog.blogspot.de/2012/08/how-to-query-sqlite-database-with.html

### Pfad zur System.Data.SQLite.dll Datei
[string]$sqlite_library_path = "C:\Program Files\System.Data.SQLite\2013\bin\System.Data.SQLite.dll"

### Pfad zur SQLite Datenbank
[string]$db_data_source = "D:\PowershellScripte\Powershell_SQLite\Serverliste2.sqlite"

### SQL Query, hier muss man entscheiden ob man bereits hier die Abfrage auf die Datenbank eingrenzt oder später im Output mit Powershell
[string]$db_query = "SELECT * FROM Servername"
oder
[string]$db_query = "SELECT * FROM Servername WHERE Hostname Like '%ADS%'"
oder
[string]$db_query = "SELECT * FROM Servername WHERE Memory <= '4096 MB'"

### http://blog.lab49.com/archives/4844
### Assembly laden, um mit SQLLite arbeiten zu können, ohne diesen Befehl würde die Abfrage nicht funktionieren.
[void][System.Reflection.Assembly]::LoadFrom($sqlite_library_path)

### Dieser Befehl stellt einen speicherinternen Datencache dar
$db_dataset = New-Object System.Data.DataSet

### Füllt die db_data_adapter Variable mit der Information der Datenbank
$db_data_adapter = New-Object System.Data.SQLite.SQLiteDataAdapter($db_query,"Data Source=$db_data_source")
[void]$db_data_adapter.Fill($db_dataset)

### Mit folgenden Befehl wird der Input der Datenbank ausgegeben
$db_dataset.Tables[0]
oder
$db_dataset.Tables[0] | Sort-Object FQDN,IPAddress,OS | Format-Table FQDN,IPAddress,OS -AutoSize

Powershell_Abfrage_1

 

 

 

 

 
Zweite Beispiel:
Gefunden bei http://poshcode.org/2879

In diesem Beispiel werden zwei Funktionen benutzt, dieses Powershell Skript speichert man sich als z.B. MySQLite.ps1 ab und lädt es sich als Modul nach.

### Import des Powershell Skriptes, nach dem Import stehen die Funktionen querySQLite und writeSQLite für Abfragen zur Verfügung
Import-Module .\Powershell_SQLite\MySQLite.ps1

### SQL Query, auch hier muss man entscheiden, ob man bereits hier die Abfrage auf die Datenbank eingrenzt oder später im Output mit Powershell
$readQuery = "SELECT * FROM Servername"
##$readQuery = "SELECT * FROM Servername WHERE Hostname Like '%ADS%'"
##$readQuery = "SELECT * FROM Servername WHERE Memory <= '4096 MB'"

$dataArray = $SQLite.querySQLite($readQuery)
$dataArray
##$dataArray | Sort-Object FQDN,IPAddress,OS | Format-Table FQDN,IPAddress,OS -AutoSize

### SQL Datensätze schreiben
$writeQuery = "INSERT INTO Servername VALUES(11,'Server11','domain.de','Server11.domain.de','192.168.0.11','255.255.255.0','192.168.0.254','192.168.0.2','192.168.0.1','192.168.0.1','Dual Core 3.07 GHz Intel Core i7 950','11264 MB','80 GB','100 GB','100 GB','Windows Server 2012 R2 x64','');"
$SQLite.writeSQLite($writeQuery)

### erneute SQL Abfrage ob der Schreibvorgang erfolgreich war
$readQuery = "SELECT * FROM Servername"
$dataArray = $SQLite.querySQLite($readQuery)
$dataArray

### Modul entfernen
Remove-Module MySQLite

Powershell_Abfrage_2

 

 

 

 

 
Powershell_Abfrage_2_2

 

 

 

 

 
Dritte Beispiel:
Gefunden bei http://psqlite.codeplex.com/

Nachdem man sich das SQLite Modul heruntergeladen und entpackt hat, kopiert man sich den Ordner in folgendes Verzeichnis

C:\Windows\System32\WindowsPowerShell\v1.0\Modules
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules

### SQLite Modul laden
if(!(Get-Module SQLite)) {Import-Module SQLite}

### Neue Datenbank erstellen oder bereits existierende mounten
New-PSDrive -PSProvider SQLite -Name HTDOM_Server_DB -Root "DataSource=D:\PowershellScripte\Powershell_SQLite\Serverliste3.sqlite"
### Mount-SQLite -Name HTDOM_Server_DB -DataSource "D:\PowershellScripte\Powershell_SQLite\Serverliste3.sqlite"

### Tabellen anlegen
New-Item -Path HTDOM_Server_DB:/Servername -Value "ID INTEGER PRIMARY KEY, Hostname TEXT, Domain TEXT, FQDN TEXT, IPAddress TEXT, SubnetMask TEXT, Gateway TEXT, DNSServer1 TEXT, DNSServer2 TEXT, WINSServer TEXT, CPU TEXT, Memory TEXT, CPartition TEXT, DPartition TEXT, EPartition TEXT, OS TEXT, ServicePack TEXT"

#NONE
#TEXT
#TEXT NOT NULL
#NUMERIC
#INTEGER
#INTEGER PRIMARY KEY
#REAL
#BLOB

### Tabellen wieder löschen
# Remove-Item -Path HTDOM_Server_DB:/Servername

### Tabellen mit Inhalt füllen
New-Item -Path HTDOM_Server_DB:/Servername -ID "1" -Hostname "Server1" -Domain "domain.de" -FQDN "Server1.domain.de" -IPAddress "192.168.0.1" -SubnetMask "255.255.255.0" -Gateway "192.168.0.254" -DNSServer1 "192.168.0.1" -DNSServer2 "192.168.0.2" -WINSServer "192.168.0.1" -CPU "Dual Core 3.07 GHz Intel Core i7 950" -Memory "1024 MB" -CPartition "80 GB" -DPartition "100 GB" -EPartition "100 GB" -OS "Windows Server 2008 R2 x64" -ServicePack "SP1"

New-Item -Path HTDOM_Server_DB:/Servername -ID "2" -Hostname "Server2" -Domain "domain.de" -FQDN "Server2.domain.de" -IPAddress "192.168.0.2" -SubnetMask "255.255.255.0" -Gateway "192.168.0.254" -DNSServer1 "192.168.0.2" -DNSServer2 "192.168.0.1" -WINSServer "192.168.0.1" -CPU "Dual Core 3.07 GHz Intel Core i7 950" -Memory "2048 MB" -CPartition "80 GB" -DPartition "100 GB" -OS "Windows Server 2012 R2 x64"
...

### Tabelleneinträge updaten
Set-Item -Path HTDOM_Server_DB:/Servername/1 -Hostname "Server3" -Domain "domain.de" -FQDN "Server3.domain.de" -IPAddress "192.168.0.3"
Get-Item -Path HTDOM_Server_DB:/Servername/1

### Tabelleneinträge löschen
Remove-Item -Path HTDOM_Server_DB:/Servername/1

### Suchen und Filtern
Get-ChildItem -Path HTDOM_Server_DB:/Servername | Select-Object FQDN,IPAddress,OS
Get-ChildItem -Path HTDOM_Server_DB:/Servername -Filter "Hostname like '%Server%'" | Format-Table FQDN,IPAddress,OS -AutoSize

FQDN              IPAddress   OS
----              ---------   --
Server1.domain.de 192.168.0.1 Windows Server 2008 R2 x64
Server2.domain.de 192.168.0.2 Windows Server 2012 R2 x64

So das war es schon wieder von mir, wünsche euch viel Spaß damit.
Gruß Helmut

Hallo zusammen,

um ein wenig von dem Grundlagentraining weg zu kommen, zeige ich euch heute, wie Ihr XML-Dateien mit Powershell nutzen könnt.
Hier habe ich euch ein kleines Howto geschrieben wie man XML-Dateien mit Microsoft Excel und Notepad vorbereitet. Zusätzlich könnt ihr hier die XML-Templates herunterladen.

XML-Dateien für Powershell vorbereiten
XML-Dateien Templates Download

Wie fragt man nun die Struktur einer XML-Datei ab? Hier ein kleines Schaubild.

XML_Visualisierung

 

 

 

 

 

Fangen wir an, eine XML-Struktur mit Powershell abzufragen. 🙂

Um mit XML-Dateien in Powershell arbeiten zu können, muss man das vorangestellte PowerShell-XML-Objektadapter [xml]$VariablenName definieren.
Die Variable wird als .NET-Klasse – System.Xml.XmlDocument deklariert. Zu finden mit:

$xmlfile | Get-Member
##XML-Datei wird in folgende Variable geladen
[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml ##serverliste3_template.xml aus dem Download
 
##Informationen aus der XML-Datei auslesen
 $xmlfile.firma
 $xmlfile.firma.land
 $xmlfile.firma.land.standorte
 $xmlfile.firma.land.standorte.standort
 $xmlfile.firma.land.standorte.standort.server
 $xmlfile.firma.land.standorte.standort.server.hostname
 $xmlfile.firma.land.standorte.standort.server.FQDN

serverliste1  serverliste2

 

 

 

 

##Die Land/Standorte/Server mit der Abfrage eingrenzen

$xmlfile.firma.land
$xmlfile.firma.land[0]
$xmlfile.firma.land[1]

serverliste3

 

 

 

 

 

$xmlfile.firma.land[0].standorte.standort
$xmlfile.firma.land[0].standorte.standort[0]
$xmlfile.firma.land[0].standorte.standort[1]
$xmlfile.firma.land[0].standorte.standort[0].server.FQDN
$xmlfile.firma.land[0].standorte.standort[1].server.FQDN
$xmlfile.firma.land[0].standorte.standort.server[0].FQDN
$xmlfile.firma.land[0].standorte.standort.server[1].FQDN

serverliste4

 

 

 

 

 

$xmlfile.firma.land.standorte[1].standort.server.FQDN
$xmlfile.firma.land.standorte.standort[2].server.FQDN
$xmlfile.firma.land.standorte.standort[3].server.FQDN
$xmlfile.firma.land.standorte.standort.server[1].FQDN
$xmlfile.firma.land.standorte.standort.server[2].FQDN

serverliste5

 

 

 

 

 

Um jetzt die Informationen von so einer XML-Datei nutzen zu können, habe ich hier mal zwei Abfragen gebaut, um meine Server anpingen zu können.

[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml
Clear-Host

$PingMachines = $xmlfile.firma.land.standorte.standort.server.FQDN

ForEach($MachineName In $PingMachines)
	{$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$MachineName'" | 
Select-Object StatusCode 
if ($PingStatus.StatusCode -eq 0)
	{Write-Host $MachineName -Fore "Green"}
else
	{Write-Host $MachineName -Fore "Red"}}

Ping2

 

 

 

 

 

$path = D:\PowershellScripte\Powershell_XML
[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml
Clear-Host

$PingMachines = $xmlfile.firma.land.standorte.standort.server | Foreach-Object {$_.'FQDN'} | Foreach-Object {

if (Test-Connection $_ -quiet -count 1){
	" " + $_  | out-file "$path\Ping_Success.txt" -append
} else {
	" " + $_ | out-file "$path\Ping_NotSuccess.txt" -append
}
 }

Ping1

 

 

 

 

 

Temporäre Änderung einer XML Struktur

[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml

$xmlfile.firma.land.standorte[0].standort.server[0] | 
ForEach-Object {if ($_.FQDN -like "ADS01.de.htdom.local")
	{$_.FQDN = "ADS01.htdom.local"
  }
 if ($_.Domain -like "de.htdom.local")
	{$_.Domain = "htdom.local"
  }
 }

 $xmlfile.firma.land.standorte[0].standort.server

XML_aendern

 

 

 

 

 

Server Liste erstellen lassen – sortiert nach IP Adressen

[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml

$xmlfile.firma.land.standorte.standort.server | Where-Object {$_."IP-Address" -gt "192.168.178.1"} | Sort-Object IP-Address | Format-Table FQDN,IPAddress,SubnetMask,Gateway,DNSServer1,DNSServer2,WINSServer -AutoSize

Servername + Domainname zusammenstellen lassen

[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml

$xmlfile.firma.land.standorte.standort.server | ForEach-Object{$_.Hostname + "." + $_.Domain} | Sort-Object $_.Hostname

Servereinträge in einer XML-Datei clonen

Clone1

[xml]$xmlfile = Get-Content .[Pfad zur XML-Datei]\serverliste3.xml

$newsrv = $xmlfile.firma.land.standorte.standort[0].server.Clone()
$newsrv.Hostname = "ADS03"
$newsrv.FQDN = "ADS03.htdom.local"
$newsrv.IPAddress = "192.168.178.102"
$newsrv.DNSServer2 = "192.168.178.102"
$newsrv.Memory = "3072 MB"
$newsrv.CPartition = "50 GB"
$newsrv.DPartition = "100 GB"
$newsrv.OS = "Windows Server 2012 R2 x64"
$newsrv.ServicePack = "-"

$newsrv2 = $xmlfile.firma.land.standorte.standort[0].server.Clone()
$newsrv2.Hostname = "ADS04"
$newsrv2.FQDN = "ADS04.htdom.local"
$newsrv2.IPAddress = "192.168.178.103"
$newsrv2.DNSServer2 = "192.168.178.103"
$newsrv2.Memory = "3072 MB"
$newsrv2.CPartition = "50 GB"
$newsrv2.DPartition = "100 GB"
$newsrv2.OS = "Windows Server 2012 R2 x64"
$newsrv2.ServicePack = "-"

$xmlfile.firma.land.standorte.standort[0].AppendChild($newsrv)
$xmlfile.firma.land.standorte.standort[0].AppendChild($newsrv2)
$xmlfile.save("D:\PowershellScripte\Powershell_XML\test.xml")

Clone2

 

 

 

 

 

So das was erst mal wieder von mir.

Viele Spaß beim ausprobieren.
Gruß Helmut

Hallo zusammen,

Im fünften Teil meiner Grundlagenserie, zeige ich euch, wie Ihr mit Variablen umgehen könnt.
Über das Thema Variablen kann man sehr dicke Bücher verfassen, daher reiße ich das Thema nur kurz an, um euch einen kleinen Überblick zu geben was möglich wäre.

Sollte mal was unklar sein, könnt ihr hier nachschlagen.

Get-Help about_Variables
Get-Help about_Automatic_Variables
Get-Help about_Environment_Variables
Get-Help about_Preference_Variables
Get-Help about_CommonParameters

Um sich die Systemvariablen anzeigen zu lassen, kann man folgende Befehle nutzen:

Get-Variable

oder

Get-ChildItem Variable: | Format-Table Name, Description -AutoSize

Die Environment/Umgebungsvariablen zeigt man sich wie folgt an:

Get-ChildItem Env: | Sort-Object Name

Bestimmte Environment/Umgebungsvariablen kann man sich anzeigen lassen, indem man Env:“ gefolgt vom Variablenamen angibt oder das Dollarzeichen „$“ davorsetzt $Env:gefolgt vom Variablenamen

Get-ChildItem Env:Computername

oder

$Env:Computername

oder

Set-Location Env:
Get-ChildItem ComputerName

Um auf Verzeichnisvariablen zugreifen zu können, benutzt man folgende Befehle:

Get-ChildItem $Env:ProgramFiles
Get-ChildItem $Env:ProgramData
Get-ChildItem $Env:ALLUSERSPROFILE

Bei 64-Bit Systemen gibt es ein Ausgabeproblem bei der Variable %ProgramFiles(x86)%, wegen der beiden Klammern um x86.
Diese Abfrage fasst man einfach in geschweifte Klammern zusammen.

Get-ChildItem ${Env:ProgramFiles(x86)}

Wenn man bei Environment/Umgebungsvariablen etwas hinzufügen möchte, bestes Beispiel wäre die Path Variable, funktioniert das wie folgt. Dies gilt aber nur für die aktive Powershellsitzung.

$Env:Path
$Env:Path = $Env:Path + ";C:\Temp" + ";D:\PowershellScripte"

Wenn man feste Werte setzen möchte, muss man das über das PowerShell-Profil realisieren. Mit folgenden cmdlet wird die Path-Erweiterung gleich in die Profildatei geschrieben.

Add-Content -Path $Profile.CurrentUserAllHosts -Value '$Env:Path = $Env:Path + ";C:\Temp" + ";D:\PowershellScripte"'

Oder folgenden Eintrag an das Ende der Profildatei schreiben.

notepad $Profile.CurrentUserAllHosts
$Env:Path = $Env:Path + ";C:\Temp" + ";D:\PowershellScripte"

Um selbst Variablen für die jeweilige Powershellsitzung zu erstellen, schreibt man $VariableName = Zuordnung

$zahl = 5
$text = "Hallo Welt"

Um eine Variable fest zu definieren, dass heißt in dieser Variable dürfen z.B. nur Ganzzahlen [integer] geschrieben werden, setzt man vor den Variablenamen ein [int],
nachdem die Variable definiert wurde und man versucht diese z.B. mit Text [string] zu überschreiben, bekommt man einen Fehlermeldung angezeigt.

[int]$zahl = 5
$zahl
5

$zahl = "Hallo Welt"

Der Wert "Hallo Welt" kann nicht in den Typ "System.Int32" konvertiert werden. Fehler: "Die Eingabezeichenfolge hat das falsche Format."
In Zeile:1 Zeichen:1
+ $zahl = "Hallo Welt"

$zahl | Get-Member (TypeName: System.Int32)

Andersherum ist der String-Variable egal ob Text oder Zahlen enthalten sind, die Zahlen werden dann einfach als Text behandelt.

[string]$text = "Hallo Welt"
$text
Hallo Welt

$text = '123'
$text
123

$text | Get-Member (TypeName: System.String)

Folgende Datentypen können für Variablen definiert werden.

[datetime] 	Datum oder Zeit
[string] 	Zeichenfolge
[char] 	Einzelnes Zeichen
[double] 	Gleitzahl mit doppelter Genauigkeit
[single] 	Gleitzahl mit einfacher Genauigkeit
[int] 	32-Bit ganze Zahl
[wmi] 	Windows Management Instrumentation (WMI) Instanz oder Sammlung
[adsi] 	Active Directory-Dienstobjekt
[wmiclass] 	WMI-Klasse
[Boolesch] 	Wahrer oder Falscher Wert

Man kann natürlich auch kleine Rechenaufgaben mit Hilfe von Variablen erledigen lassen. 🙂

$rechnung = 100
$mwst = 100 * 0.19
$endsumme = $rechnung + $mwst
Write-Host "Mensch, das Abendessen hat heute $endsumme Euro gekostet!"

Oder ganze Abfragen in einer Variable schreiben lassen und diese später wieder auswerten oder weiterverarbeiten.

$timedate = Get-Date -Format "dd-MM-yyyy_HH-mm-ss"
$computers = Get-ADComputer -filter "Name -like '*'" -properties OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion,IPv4Address,Created | Sort-Object

Spezielle Variablen kann man wie folgt definieren. Ob es Sinnvoll ist, muss jeder für sich selbst entscheiden. 🙂

${ein sonderbarer, aber */() möglicher Variablenname} = 12

Array’s definiert man wie folgt.

##Zahlen-Array's erstellen
$ZahlenArray = 1,2,3 ##Ausgabe des Array's = $ZahlenArray; $ZahlenArray[0]; $ZahlenArray[1]; $ZahlenArray[2]
$ZahlenArray = '4', '5', '6'
$ZahlenArray = "7", "8", "9"
$ZahlenArray = @("10", "11", "12")
$ZahlenArray

##String-Array's erstellen
$StringArray = 'Wert 1', 'Wert 2', 'Wert 3' 
$StringArray = Write-Output 'Wert 4' 'Wert 5' 'Wert 6' 
$StringArray = 'Wert 7,Wert 8,Wert 9'.Split(',')
$StringArray = @("Wert 10", "Wert 11", "Wert 12")
$StringArray

##Einträge im Array können wie folgt verändert werden
$StringArray[2] = "Wert 14"
$StringArray

##Möchte man die Ausgabe bestimmter oder aller Werte in einer Array manipulieren, hilft wieder das cmdlet Get-Member
$StringArray | Get-Member

$StringArray[1].ToLower()
$StringArray.ToUpper()
$StringArray.Replace("Wert 10", "Wert 15")

Sucht man nach bestimmten Strings oder Zeichenketten in einer Variable, helfen die Methoden (Get-Member)

$uncPath = "\\Servername\Freigabe"
$uncPath

$uncPath.StartsWith("\\")
True

if ($uncPath.StartsWith("\\") -eq $True) {
	Write-Host "Der UNC Pfad beginnt mit '\\'"
} else {
	Write-Host "Der UNC Pfad beginnt leider nicht mit '\\'"
}

$uncPath.EndsWith("Freigabe")
True

$uncPath.EndsWith("e")
True

$uncPath.EndsWith("f")
False

Um Hash-Table’s erstellen zu können, benötigt man einen Namen und ein Value als Zuordnung. Es gibt verschiedene Möglichkeiten die Wertepaare in einer Hash-Table abzulegen.

$cplist1 = @{ComputerName = "CLN01"; IPAddress="192.168.100.111"; UserName="Peter Pan"; Standort="Berlin"; Domain="htdom.local"}

oder

$cplist2 = @{} #Leere Hash-Table erstellen

$cplist2.ComputerName = "CLN01" 
$cplist2.IPAddress = "192.168.100.111"
$cplist2.UserName = "Peter Pan"
$cplist2.Standort = @("Berlin")
$cplist2["Domain"] = "htdom.local"  

##Werte aus einer Hash-Table abfragen
$cplist2
$cplist2["UserName"]
$cplist2.UserName
$cplist2["UserName", "ComputerName", "Standort"]

##Einträge aus einer Hash-Table wieder löschen
$cplist2.Remove("Domain")

##Hash-Table komplett leeren, zurück bleibt die leere Variable
$cplist2.Clear

Get-Variable
...
cplist2                         {}

##Diese leere Variable kann man mit Remove-Variable löschen
Remove-Variable cplist2

Noch ein Beispiel für eine Hash-Table

$hash = $null
$hash = @{}
$services = Get-Service | Sort-Object Name

ForEach ($service in $services) {$hash.add($service.Name,$service.Status)}
Clear-Host

$hash
$hash["BITS"]
$hash["BITS", "VSS"]

Und sollten mehrere Werte in das Value Feld eingetragen werden, würde es mit diesen Beispiel funktionieren.
Die Werte im Value Feld lassen sich aber nicht mehr so leicht verändern wie oben in den Beispielen gezeigt, hier müssten die kompletten Werten gelöscht und mit neuen Werten hinzugefügt werden.

$Users = @{}
$Users.Administrator += @("DOMAIN\Administrator")
$Users.Administrator += @("DOMAIN")
$Users.Administrator += @("S-1-5-21-3775395870-3833774050-3544682504-500")
$Users.Gast += @("DOMAIN\Gast")
$Users.Gast += @("DOMAIN")
$Users.Gast += @("S-1-5-21-3775395870-3833774050-3544682504-501")

$Users
Name                           Value
----                           -----
Administrator                  {DOMAIN\Administrator, DOMAIN, S-1-5-21-3775395870-3833774050-3544682504-500}
Gast                           {DOMAIN\Gast, DOMAIN, S-1-5-21-3775395870-3833774050-3544682504-501}

$Users["Administrator"]
DOMAIN\Administrator
DOMAIN
S-1-5-21-3775395870-3833774050-3544682504-500

$Users["Gast"]
DOMAIN\Gast
DOMAIN
S-1-5-21-3775395870-3833774050-3544682504-501

$Users.Remove("Gast")

$Users
Name                           Value
----                           -----
Administrator                  {DOMAIN\Administrator, DOMAIN, S-1-5-21-3775395870-3833774050-3544682504-500}

$Users.Clear

Get-Variable
...
Users                          {}

Remove-Variable Users

So das war es erst mal wieder von mir.

Wünsche viel Spaß und viele Grüße
Helmut

Hallo zusammen,

Im vierten Teil meiner Grundlagenserie zeige ich euch wie ein cmdlet Befehl aufgebaut ist und wie Ihr PowerShell für die tägliche Arbeit nutzen könnt.

Die PowerShell Syntax sieht wie folgt aus = Verb Bindestrich „-“ Substantiv -Parameter Attribut, das ganze in Englisch und in der Einzahl.

Es gibt kein Get-Members/Get-Processes/Get-Services, sondern nur ein Get-Member/Get-Process/Get-Service

Alle Parameter, die man dem cmdlet mit gibt, kann man bis auf ein Zeichen nach dem Bindestrich „-“ abkürzen, solange es keinen weiteren Parameter mit demselben Buchstaben gibt.
Bestes Beispiel wäre jetzt hier das cmdlet Get-ChildItem, hier gibt es als Parameter -Filter -File -Force

Die gekürzte Version würde jetzt wie folgt aussehen: Get-ChildItem -Filt BlaBlaBla -File BlaBlaBla -Fo
Persönlich schreibe ich aber die Parameter aus, dann kann nichts schief gehen und jeder der das Skript liest, weiß was gemeint ist.

Auch ist es möglich die Parameter ganz weg zu lassen, dann muss aber die Reihenfolge der Parameter eingehalten werden. Die Reihenfolge könnt Ihr euch anzeigen lassen, indem Ihr Get-Help cmdlet aufruft.

Powershell Verben:
Get- besorgt Informationen
Set- ändert Informationen
Add- fügt neue Informationen hinzu
Remove- löscht Informationen

Eine Beschreibung aller PowerShell Verben findet ihr auf der MSDN Seite von Microsoft oder mit dem cmdlet Get-Verb
http://msdn.microsoft.com/en-us/library/ms714428%28v=vs.85%29.aspx

Powershell Substantiv:
Help
Member
Service
Command

So dann wollen wir mal loslegen, jede gute Programmiersprache beginnt mit einem „Hello World“, Powershell beginnt meistens mit Get-Process oder Get-Service, dem schließe ich mich jetzt an.

Ich lass mir mal alle meine lokalen Dienste anzeigen:

Get-Service

Um mir alle Dienste nach Namen/Status/DisplayName zu sortieren, benutze ich die Pipeline „|“ und das cmdlet Sort-Object

Get-Service | Sort-Object Name
Get-Service | Sort-Object Status
Get-Service | Sort-Object DisplayName

Um nach bestimmten Diensten zu suchen die ein „win“ in Ihren Namen haben, benutze ich folgende Abfrage

Get-Service -Name *win*

Mit folgendem Befehl finde ich heraus mit welchen zusätzlichen Eigenschaften ich die Dienste noch abfragen kann. Besonderes Augenmerk sind die Property’s

Get-Service | Get-Member

TypeName: System.ServiceProcess.ServiceController

Name                      MemberType    Definition
----                      ----------    ----------
Name                      AliasProperty Name = ServiceName
RequiredServices          AliasProperty RequiredServices = ServicesDependedOn
...
CanPauseAndContinue       Property      bool CanPauseAndContinue {get;}
CanShutdown               Property      bool CanShutdown {get;}
CanStop                   Property      bool CanStop {get;}
Container                 Property      System.ComponentModel.IContainer Container {get;}
DependentServices         Property      System.ServiceProcess.ServiceController[] DependentServices {get;}
DisplayName               Property      string DisplayName {get;set;}
MachineName               Property      string MachineName {get;set;}
ServiceHandle             Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}
ServiceName               Property      string ServiceName {get;set;}
ServicesDependedOn        Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}
ServiceType               Property      System.ServiceProcess.ServiceType ServiceType {get;}
Site                      Property      System.ComponentModel.ISite Site {get;set;}
Status                    Property      System.ServiceProcess.ServiceControllerStatus Status {get;}

Um mir die Eigenschaften einer Abfrage anzeigen zu lassen, muss diese Abfrage in Klammern gesetzt werden, plus einen Punkt und die dazugehörige Eigenschaft.
Hinter der Eigenschaft sieht man auch in geschweiften Klammern {get;set;}. Das bedeutet, dass diese Eigenschaft bei Get und Set Abfragen benutzt werden kann.

(Get-Service Adobe*).CanPauseAndContinue
False
False
Get-Service Adobe* | Format-List -Property Name,CanPauseAndContinue
Name                : AdobeARMservice
CanPauseAndContinue : False

Name                : AdobeFlashPlayerUpdateSvc
CanPauseAndContinue : False
Get-Service Adobe* | Format-List -Property *
Name                : AdobeARMservice
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : True
DisplayName         : Adobe Acrobat Update Service
DependentServices   : {}
MachineName         : .
ServiceName         : AdobeARMservice
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Running
ServiceType         : Win32OwnProcess
Site                :
Container           :

Name                : AdobeFlashPlayerUpdateSvc
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : False
DisplayName         : Adobe Flash Player Update Service
DependentServices   : {}
MachineName         : .
ServiceName         : AdobeFlashPlayerUpdateSvc
ServicesDependedOn  : {}
ServiceHandle       : SafeServiceHandle
Status              : Stopped
ServiceType         : Win32OwnProcess
Site                :
Container           :

Um Dienste mit der Powershell starten und stoppen zu können, benutzt man das cmdlet Start/Stop-Service

Get-Service -Name AdobeARMservice

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service


Stop-Service -Name AdobeARMservice; Get-Service -Name AdobeARMservice

Status   Name               DisplayName
------   ----               -----------
Stopped  AdobeARMservice    Adobe Acrobat Update Service


Start-Service -Name AdobeARMservice; Get-Service -Name AdobeARMservice

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service

Noch ein schönes Feature ist das cmdlet Out-GridView

Get-Service | Out-GridView

Out_GridView

 

 

 

 

 

Um den Starttyp von einen Dienst zu verändern, benutzt man das cmdlet Set-Service

Set-Service -Name AdobeARMservice -StartupType Manual

Leider gibt es aber keine Eigenschaft für das cmdlet Get-Service, die mir den Starttyp eines Dienstes zurückgibt. Hier muss man sich mit dem cmdlet Get-WmiObject weiterhelfen.

(Get-WmiObject Win32_Service -filter "Name='AdobeARMservice'").StartMode
Manual

oder

Get-WmiObject -Query "Select StartMode From Win32_Service Where Name='AdobeARMservice'"
Get-WmiObject -Class Win32_Service -Property StartMode -Filter "Name='AdobeARMservice'"
__GENUS          : 2
__CLASS          : Win32_Service
__SUPERCLASS     :
__DYNASTY        :
__RELPATH        :
__PROPERTY_COUNT : 1
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
StartMode        : Manual
PSComputerName   :

Mit folgender Abfrage kann man sich alle Dienste anzeigen lassen, die gestoppt bzw. gestartet sind.

Get-Service | Where-Object {$_.Status -eq "Stopped"}
Get-Service | Where-Object {$_.Status -eq "Running"}

Nun bringen wir ein bisschen Farbe ins Spiel, mit folgender Abfrage kann man sich die Dienste je nach Status farbig hervorheben lassen.
Dazu gibt es ein weiteres cmdlet Write-Host mit der Eigenschaft -ForegroundColor.

Get-Service | ForEach-Object{if($_.Status -eq "Stopped"){Write-Host $_.Name $_.Status -ForegroundColor red} else {Write-Host $_.Name $_.Status -ForegroundColor green}}

Um sich das ganze in eine HTML Datei exportieren zu lassen, benutzt man folgende Abfrage.

$datetime = get-date -uformat "%d-%m-%Y_%H-%M-%S"
Get-Service -ComputerName localhost | ConvertTo-Html -Property DisplayName,Status | ForEach-Object {if ($_ -Like "*<td>Running</td>*") {$_ -Replace "<tr>", "<tr bgcolor=green>"} else {$_ -Replace "<tr>", "<tr bgcolor=red>"}} > D:\Dienste_$datetime.html
Start D:\Dienste_$datetime.html

HTML_Report

 

 

 

 

 

Wenn unter euch ein paar Designer sind, gibt es noch einen schöneren Bericht, der die Prozesse auch gleich mitabdeckt.
Dieses CodeSnippet habe ich im Internet gefunden, leider weiß ich nicht mehr woher. (Vielen Danke an den Codeverfasser)

#Generate our HTML Tables
$FileLocation = "C:\Temp\Report.html"

$Services = Get-Service | Select-Object DisplayName, Status | ConvertTo-Html -Fragment
$Process = Get-Process | Select-Object Name, CPU | Sort-Object CPU -Descending | ConvertTo-Html -Fragment

#Color the service column
$Services = $Services | ForEach {$_ -Replace "<td>Running</td>","<td style=`"color: green`">Running</td>"}
$Services = $Services | ForEach {$_ -Replace "<td>Stopped</td>","<td style=`"color: red`">Stopped</td>"}

#Generate our full HTML with CSS styling
$HTML = ConvertTo-Html -Body "$Services $Process" -Head "<style> body {background-color: lightblue; font-size: 12px; } table {background-color: white; margin: 5px; float: left; top: 0px; display: inline-block; padding: 5px; border: 1px solid black} tr:nth-child(odd) {background-color: lightgray} </style>"

#Output to a file
$HTML | Out-File $FileLocation

ii $FileLocation

HTML_Report2

 

 

 

 

 

Das war es erst mal wieder von mir.

Wünsche viel Spaß beim rumspielen und testen, bis die Tage.
Gruß Helmut

Hallo zusammen,

Im dritten Teil meiner Grundlagenserie zeige ich euch wie ihr euer Skriptumgebung anpassen könnnt.

Als Skript Editor nutze ich persönlich Notepad++ und die Powershell ISE, derzeit reicht mir das vollkommen aus.

Trotzdem hier eine kleine Liste von sehr guten Powershell Editoren.

Admin Script Editor (ASE) = http://www.itninja.com/community/admin-script-editor
PowerShell Plus – Idera = http://www.idera.com/productssolutions/freetools/powershellplus
DELL PowerGUI Script Editor = http://en.community.dell.com/techcenter/powergui/m/
PrimalScript 2014 = http://www.sapien.com/software/primalscript

Mit den Powershell Snippet Manager könnt ihr eure zahlreichen Skripte übersichtlich verwalten, arbeitet sehr eng mit der Dell PowerGUI zusammen.
Powershell Snippet Manager = http://bytecookie.wordpress.com/snippet-manager/

Hier die Hilfe rund um das Thema Profil

Get-Help about_Profiles

Um sich ein eigenes Powershell Profil einrichten zu können, sollte man die Pfade dorthin kennen. Es gibt 6 Profile, die man sich anlegen kann.

$PROFILE | fl * -Force

oder

$Profile | Get-Member
$Profile | Get-Member -MemberType NoteProperty

AllUsersAllHosts = %SystemRoot%\System32\WindowsPowerShell\v1.0\profile.ps1
AllUsersCurrentHost = %SystemRoot%\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
AllUsersCurrentHost = %SystemRoot%\System32\WindowsPowerShell\v1.0\Microsoft.PowerShellISE_profile.ps1

CurrentUserAllHosts = %USERPROFILE%\Documents\WindowsPowerShell\profile.ps1
CurrentUserCurrentHost = %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
CurrentUserCurrentHost = %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

AllUsersAllHosts = Profil ist für alle Benutzer und alle Powershell Sitzungen gültig
AllUsersCurrentHost = Profil ist für alle Benutzer und nur die aktive Powershell Sitzungen gültig.
CurrentUserAllHosts = Profil ist nur für den aktiven Benutzer und alle Powershell Sitzungen gültig.
CurrentUserCurrentHost = Profil ist nur für den aktiven Benutzer und nur die aktive Powershell Sitzungen gültig.

Sollte es mal vorkommen dass alle Profile existieren, wird folgende Reihenfolge von Powershell abgearbeitet.

1. %SystemRoot%\System32\WindowsPowerShell\v1.0\profile.ps1
2. %SystemRoot%\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1
3. %USERPROFILE%\Documents\WindowsPowerShell\profile.ps1
4. %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Ich persönlich habe mir angewöhnt, nur das CurrentUserAllHosts Profil zu nutzen. Damit decke ich alle Powershell Versionen (x86, x64, ISE) auf meinen Rechner ab.

Mit folgenden Befehlen überprüft man, ob eine Profildatei vorhanden ist.

Test-Path $PROFILE.CurrentUserAllHosts ## Wenn der Wert false ist, legt man sich eine neue Profildatei an
New-Item –Type file –Force $PROFILE.CurrentUserAllHosts

Mit diesen Befehl kann man nochmal nachsehen, ob die Datei auch wirklich vorhanden ist. 🙂

Get-ChildItem $env:USERPROFILE\Documents\WindowsPowerShell
notepad $PROFILE.CurrentUserAllHosts

Und hier meine Beispiel Profildatei:

### profile.ps1 - Anfang ###
#
# Angepasstes Powershell Profil
# Last modified: 12.04.2014

# Setzen das Startverzeichnis
Set-Location "D:\PowershellScripte" ## Ordner muss vorhanden sein

# Angepasster Prompt
function prompt {
$msg = "HTDOM $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1))"
Write-Host -ForegroundColor Blue -NoNewLine $msg; " "
}

# Angepasster Powershell Titel
$a = (Get-Host).UI.RawUI
$a.WindowTitle = "HTDOM - Powershell"

# Setzt bestimmte Alias und Funktionen
function pss{Set-Location D:\PowershellScripte}
function c{set-location C:\}
function d{Set-Location D:\}

function .. {cd ..}
function ... {cd ..\..}
function .... {cd ..\..\..}
function ..... {cd ..\..\..\..}

function ws {Set-Location C:\Windows\System32}
function npp {notepad $PROFILE.CurrentUserAllHosts}
function np {start "C:\Program Files (x86)\Notepad++\notepad++.exe"}
function ise {start "C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe"}
function module {Get-Module -ListAvailable | Where-Object {$_.Path -like "$PSHOME*"} | Import-Module}
function about {Get-Help About_ | select name, synopsis | format-table -auto}
function kb($id) {Start-Process "http://support.microsoft.com/kb/$id"}
function applog {Get-EventLog Application -newest 100}
function syslog {Get-EventLog System -newest 100}

set-alias -Name gs -Value get-service –Description "mein: get-service"
set-alias -Name gh -Value get-help –Description "mein: get-help"
set-alias -Name tp -Value test-path –Description "mein: test-path"

### profile.ps1 - Ende ###

Wer einen Tapetenwechsel für die PowerShell Konsole haben möchte, findet hier eine sehr guten Artikel.
http://tobivnext.wordpress.com/2012/03/07/powershell-konsoleneigenschaften-anpassen/

Kleiner Tipp noch am Rande, im Artikel wird das Wort fallen RGB Farben sind in BGR Format anzugegeben. Das heißt
Im Hexadezimalwert wird einfach das R und B vertauscht. Sachen gibt es. 🙂

RGB Farbe = #112233 = Dunkles Türkis Blau
BGR Farbe = #223311

Viele Spaß und bis die Tage
Helmut

Hallo zusammen,

das wichtigste zuerst, wenn man sich nun intensiver mit PowerShell beschäftigen möchte, muss man seine Umgebung anpassen, um lokal Skripte ausführen zu können/dürfen.

Dazu dient das cmdlet „Set-ExecutionPolicy

Es gibt 5 verschieden Policy Einstellungen

Restricted = Die Powershell führt keine Skripte aus. Das ist der Defaulwert für die Powershell.
AllSigned = Die Powershell startet nur Skripte, die eine digitale Signatur haben.
RemoteSigned = Die Powershell wird keine Skripte ausführen, die aus dem Internet stammen – außer sie haben eine digitale Signatur.
Unrestricted = Die Powershell ignoriert die digitalen  Signatur, fragt aber nach, ob ein Skript, das aus dem Internet stammt, ausgeführt werden soll.
Bypass = Alle Skripte werden ohne Nachfrage ausgeführt (Sehr unsicher)

Undefined = Setzt den Defaultwert auf Restricted, sobald Gruppenrichtlinien im Einsatz sind, hat dieser Schalter keine Auswirkung.

Wenn man nun lokal Skripte ausführen möchte, setzt man dementsprechend seine ExecutionPolicy

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : Restricted
Set-ExecutionPolicy RemoteSigned

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts bei. Wenn Sie die Ausführungsrichtlinie ändern, sind Sie möglicherweise den im
Hilfethema "about_Execution_Policies" unter "http://go.microsoft.com/fwlink/?LinkID=135170" beschriebenen Sicherheitsrisiken ausgesetzt. Möchten Sie die
Ausführungsrichtlinie ändern?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): J

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : RemoteSigned
Set-ExecutionPolicy Unrestricted

Ausführungsrichtlinie ändern
Die Ausführungsrichtlinie trägt zum Schutz vor nicht vertrauenswürdigen Skripts bei. Wenn Sie die Ausführungsrichtlinie ändern, sind Sie möglicherweise den im
Hilfethema "about_Execution_Policies" unter "http://go.microsoft.com/fwlink/?LinkID=135170" beschriebenen Sicherheitsrisiken ausgesetzt. Möchten Sie die
Ausführungsrichtlinie ändern?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): J

Get-ExecutionPolicy -List | Format-List

Scope           : MachinePolicy
ExecutionPolicy : Undefined

Scope           : UserPolicy
ExecutionPolicy : Undefined

Scope           : Process
ExecutionPolicy : Undefined

Scope           : CurrentUser
ExecutionPolicy : Undefined

Scope           : LocalMachine
ExecutionPolicy : Unrestricted

Sobald man aber in einen Firmenumfeld Powershell Skripte einsetzen möchte, sollte man seine fertigen Skripte mit einem Zertifikat signieren. Ob das Sinnvoll ist oder nicht, muss natürlich jeder für sich selbst entscheiden. Es gibt natürlich auch hier Mittel und Wege das ganze auszuhebeln, aber für unerfahrene Mitstreiter eine kleine Lebensaufgabe.

Hier die Vorbereitung um Firmenweit seine Powershellskripte zu signieren:
Als erstes erstelle ich eine neue Gruppenrichtlinien für die Domain, diese Gruppenrichtlinie verknüpfe ich mit der Domain.

Computerkonfiguration –> Richtlinien –> Administrative Vorlagen –> Windows-Komponenten –> Windows Powershell –> Skriptausführung aktivieren (Nur signierte Skripte zulassen)

GPO

 

 

 

 

 

GPO_Shortcut

 

 

 

 

 

Wenn man nun mit gpupdate /force die Gruppenrichtlinien aktualisiert, bekommt man beim Öffnen von PowerShell eine Fehlermeldung. (Bei mir war bereits eine PowerShell Profildatei hinterlegt)

PowershellError

 

 

 

 

 

Danach erstelle ich mir in Active Directory eine neue Rollengruppe und füge alle Mitglieder hinzu, die PowerShellSkripte signieren dürfen.

Rollengruppe

 

 

 

 

 

Jetzt öffne ich meine AD Zertifizierungsstelle und lege eine neue Zertifikatsvorlage an. Diese Zertifikatsvorlage Veröffentliche ich im Anschluss.

Zertifikatsvorlage1

 

 

 

 

 

Zertifikatsvorlage2

 

 

 

 

 

Zertifikatsvorlage3

 

 

 

 

 

Alle Benutzer die berechtigt sind, Skripte zu signieren. Öffnen nun eine neue MMC Konsole und fügen sich das SnapIn Zertifikate/Eigenes Benutzerkonto hinzu.

Unter Eigene Zertifikate –> Zertifikate –> Neu Aufgaben –> Neues Zertifikat anfordern, fordern nun die Benutzer ein Codesigning Zertifikat an.

Zertifikat_anfordern1

 

 

 

 

 

Zertifikat_anfordern2

 

 

 

 

 

Und mit folgenden beiden Befehlen kann man seine Skripte signieren

$Cert = Get-ChildItem Cert:\CurrentUser\My\ -Recurse -CodeSigningCert
Set-AuthenticodeSignature <Pfad>\PowershellScript.ps1 $Cert

Script_Signieren

 

 

 

 

 

Powershell_ohne_Error

 

 

 

 

 

Sobald die Gruppenrichtlinie AllSigned gesetzt wurde, kann man diese nicht mehr !vorübergehen! außer Kraft setzen.

keine_aenderung_moeglich

 

 

 

 

 

Viel Spaß und bis die Tage
Helmut

Hallo zusammen,

da ich mich momentan wieder sehr intensiv mit PowerShell beschäftige, möchte ich nicht all mein Wissen hier auf meiner Festplatte verstauben lassen.
In den nächsten Tagen und Wochen werde ich von den Grundlagen bis zu fertigen Beispielskripten alles hier posten.

PowerShell rückt von Tag zu Tag immer mehr in den Vordergrund und löst endlich, oder vielleicht auch Gott sei Dank, die gute alte CMD Konsole ab.
Umso früher man sich mit PowerShell beschäftigt, umso leichter wird auch der Umstieg sein.

Derzeit arbeite ich mit der PowerShell Version 3
Voraussetzung um PowerShell 3 auf Windows 7 einsetzen zu können, ist das Microsoft .NET Framework 4.0, besser wäre natürlich gleich das Microsoft .NET Framework 4.5.1
http://www.microsoft.com/de-de/download/details.aspx?id=40779

Nachdem Microsoft .NET Framework 4.5.1 installiert ist, benötigt man noch das Windows Management Framework 3.0
http://www.microsoft.com/en-us/download/details.aspx?id=34595

Nach der Installation, kann man sich mit den folgenden Befehl die PowerShell Version anzeigen lassen.

$PSVersionTable

Name                           Value
----                           -----
PSVersion                      3.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18444
BuildVersion                   6.2.9200.16481
PSCompatibleVersions           {1.0, 2.0, 3.0}
PSRemotingProtocolVersion      2.2

Wenn alles sauber installiert wurde und die Version passt, geht es an die Hilfedateien. Diese müssen für die PowerShell 3 aus dem Internet heruntergeladen werden.

Folgender Befehl lädt die Dateien aus dem Internet

Update-Help -UICulture en-us -Force

Sollte man an bestimmten Arbeitsplätzen keinen Internetzugriff haben, muss man einen kleinen Umweg gehen.
Ich besorge mir von einem bestehenden Client, mit aktueller PowerShell 3.0, mit folgendem Befehl die passenden Hilfedateien.

mkdir C:\temp\Hilfedateien\en-US 
oder
New-Item -Type Directory C:\temp\Hilfedateien\en-US -Force
Save-Help -UICulture en-us -DestinationPath C:\temp\Hilfedateien\en-US -Force

Und spiele diese auf den passenden Arbeitsplätzen ohne Internetzugriff wieder ein.

Update-Help -SourcePath C:\temp\Hilfedateien\en-US -UICulture en-us -Force

Da derzeit die Hilfe nur in Englisch verfügbar ist, navigiere ich in folgendes Verzeichnis

C:\Windows\System32\WindowsPowerShell\v1.0\en-US

kopiere mir alle Hilfe Textdateien und füge sie hier wieder ein.

C:\Windows\System32\WindowsPowerShell\v1.0\de-DE
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\de-DE

oder mit

Copy-Item C:\Windows\System32\WindowsPowerShell\v1.0\en-US\*.* -Destination C:\Windows\System32\WindowsPowerShell\v1.0\de-DE -Recurse
Copy-Item C:\Windows\System32\WindowsPowerShell\v1.0\en-US\*.* -Destination C:\Windows\SysWOW64\WindowsPowerShell\v1.0\de-DE -Recurse

Wenn das alles erledigt ist, fangen wir an uns mit der Hilfe vertraut zu machen.

Get-Help
Get-Help *
Get-Help cmdlet (Get-Help Copy-Item)
Get-Help cmdlet -Full/-Detailed/-Examples/-Online (Get-Help Copy-Item -Full/-Detailed/-Examples/-Online)

Wenn man sich die komplette Hilfe speichern möchte, dann funktioniert das mit diesen beiden Befehlen.
Die Hilfe umfasst ca. 130.000 Textzeilen und das sind noch nicht mal alle cmdlets, die für die PowerShell angeboten werden.

$HelpFile = Get-Help *
$HelpFile | Get-Help -Detailed | Out-File D:\PowershellScripte\Powershell_Hilfe.txt

Weitere wichtige Befehle sind der Get-Command, Get-Member und Get-Alias Befehl. Man kann sich nicht alle Befehle merken, aber man kann danach suchen.

Get-Command *copy*
Get-Command Remove*
Get-Command -CommandType All
Get-Command -CommandType Alias -All
Get-Command -CommandType cmdlet
Get-Help Get-Command -Parameter *

Get-Help about_ | Select-Object Name,Synopsis | Format-Table -AutoSize
Get-Help about_Wildcards

Get-Help about_Automatic_Variables
Get-Help about_Variables
Get-Help about_Environment_Variables

Get-Help Get-Member -Full
Get-Alias -Definition Get-ChildItem | Format-Table -AutoSize

Um sich Alias anzeigen zu lassen, benutzt man z.B.

Get-Command -CommandType Alias -All
Get-Alias c*

Um sich seine History von Befehlen anzeigen zu lassen, benutzt man Get-History oder F7 (Taste Pfeil Hoch/Pfeil Runter)
Gerade am Anfang kann man sich seine ersten Schritte in PowerShell aufzeichnen lassen, hierzu dienen diese beiden Befehle (Start und Stop-Transcript), alles was zwischen den beiden Befehlen passiert, wird in eine Datei gespeichert.

Start-Transcript C:\Temp\CaptureDemo.txt

Get-Command *copy*
Get-Command Remove*

Stop-Transcript; notepad C:\Temp\CaptureDemo.txt

Woher beziehe ich mein Powershell Wissen.

Microsoft TechNet = http://technet.microsoft.com/de-de/library/ff742278.aspx
Powershell Praxis = http://www.powershellpraxis.de/
NT4 Admins = http://www.nt4admins.de/themen/powershell.html
Script resources for IT professionals = http://gallery.technet.microsoft.com/scriptcenter
YouTube = http://www.youtube.com/results?search_query=Powershell+Grundlagen

Wünsche euch viel Spaß

Gruß Helmut