Zum Inhaltsverzeichnis
---------------------------------------------------------------------------------------
1 Pfade
Der erste Block eines Skriptes, das sich mit Objekten im Filesystem beschäftigt, dürfte wohl meistens der Weg zum gewünschten Verzeichnis sein, in dem irgendetwas unternommen werden soll. Entweder bewegt man das aktuelle Arbeitsverzeichnis der Powershellsession gleich komplett zum Ziel, sowie man das aus der commandshell (cmd.exe "cd /d c:\temp") gewöhnt ist, oder gibt seinen Powershellbefehlen den richtigen Pfad jedesmal mit.
Liegt der Zielpfad bereits vor, so ist das Navigieren zu dem Pfad natürlich einfach. Muss man den Zielpfad erst neu konstruieren, so helfen eine Reihe von cmdlets weiter. Im nächsten Unterkapitel
Im Kaptilel
1.1 spezielle Pfade
Zwei Tipps zu Beginn:
- Wenn im Skript das aktuelle Arbeitsverzeichnis verändert wird, so merkt euch vor der Änderung dieses Verzeichnis und setzt das Arbeitsverzeichnis am Ende des Skripts wieder auf die Ausgangsposition - siehe Beispiel 1c unter
Für den Skriptbenutzer ist das einfach angenehmer.
- Arbeitet möglichst mit den in Windows, .Net oder in der Powershell vordefinierten Pfaden. Dadurch erreicht ihr, daß euer Skript kompatibler über verschiedene Betriebssystemversionen, Architekturversionen(32/ 64 bit) und Sprachversionen ist, als mit selbst zusammengesetzten Pfaden, die vielleicht nur auf eurem Entwicklerrechner existieren.
1.1.1 wo sind "spezielle Pfade" hinterlegt
Ich zeige hier drei Möglichkeiten, die ein Powershellprogrammierer nutzen kann, um spezielle Dateien und Verzeichnisse zu ermitteln.
- automatic Variables
- Umgebungsvariablen
- Eigenschaften von .Net Klassen (Registry)
1.1.1.1 automatic Variables
Technet:
Neben vielen anderen Variablen enthalten die "automatic variables" Liste 6 Variablen, die recht häufig vorkommende Pfade beinhalten.
Beispiel 1a: Liste der Pfadvariablen unter den "automatic variables"
Lest euch die Beschreibungen einfach mal durch. Einige Variablen davon sind euch bestimmt schon begegnet. Beispielwerte von einem Windows7 System findet ihr im nach folgenden Beispiel 1b.
get-help about_automatic_variables
#Ausgabe gekürzt
$Home
Enthält den vollständigen Pfad zum Stammverzeichnis des
Benutzers. Diese Variable ist die Entsprechung der
%homedrive%%homepath%-Umgebungsvariablen, normalerweise
"C:\Dokumente und Einstellungen\<Benutzer>".
....
$MyInvocation
Enthält ein Objekt mit Informationen zum aktuellen Befehl,
z. B. ein Skript, eine Funktion oder einen Skriptblock.
Mithilfe der Informationen im Objekt, z. B. mit dem Pfad und dem
Dateinamen des Skripts ($myinvocation.mycommand.path) oder mit dem
Namen einer Funktion ($myinvocation.mycommand.name), können Sie den
aktuellen Befehl bestimmen. Dies ist besonders hilfreich beim Suchen
des Namens des derzeit ausgeführten Skripts.
....
$Profile
Enthält den vollständigen Pfad des Windows PowerShell-Profils
für den aktuellen Benutzer sowie der aktuellen Hostanwendung.
Mithilfe dieser Variablen können Sie das Profil in Befehlen
darstellen. Mit der Variablen können Sie beispielsweise in
einem Befehl bestimmen, ob ein Profil erstellt wurde:
test-path $profile
Mit der Variablen können Sie in einem Befehl auch ein Profil
erstellen:
new-item -type file -path $pshome -force
Darüber hinaus können Sie sie in einem Befehl verwenden, um
das Profil in Editor zu öffnen:
notepad $profile
....
$PsHome
Enthält dem vollständigen Pfad des Installationsverzeichnisses für
Windows PowerShell, normalerweise "%windir%\System32\WindowsPowerShell
\v1.0". Sie können diese Variable in den Pfaden für Windows
PowerShell-Dateien angeben. Mit dem folgenden Befehl werden z. B. die
konzeptuellen Hilfethemen nach dem Wort "Variable" durchsucht:
select-string -pattern variable -path $pshome\*.txt
....
$PSScriptRoot
Enthält das Verzeichnis, aus dem das Skriptmodul ausgeführt wird.
Diese Variable ermöglicht Skripts den Zugriff auf andere
Ressourcen über den Modulpfad.
....
$Pwd
Enthält ein Pfadobjekt, das den vollständigen Pfad des
aktuellen Verzeichnisses darstellt.
....
SEE ALSO
about_Hash_Tables
about_Preference_Variables
about_Variables
Beispiel 1b: Werte der Pfadvariablen
"`$Home: {0}" -f $home
"`Skriptpfad: {0} -f $($MyInvocation.InvocationName)
"`$Profile: {0}" -f $Profile
"`$PsHome: {0}" -f $PsHome
"`$PSScriptRoot: {0}" -f $PSScriptRoot
"`$Pwd: {0}" -f $Pwd
#Ausgabe
$Home: C:\Users\karl_napf
Skriptpfad: C:\Powershell\MyScripts\test.ps1
$Profile: C:\Users\karl_napf\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
$PsHome: C:\Windows\System32\WindowsPowerShell\v1.0
$PSScriptRoot:
$Pwd: C:\Powershell\MyScripts
Im Gegensatz zu den anderen 4 Variablen, sind die Variablen $pwd und $MyInvocation keine Strings der Klasse [system.string], sondern $pwd ist ein Objekt der Klasse [System.Management.Automation.PathInfo] und $MyInvocation ist ein Object der Klasse [System.Management.Automation.InvocationInfo]. Auf $MyInvocation gehe ich im Unterkapitel 1.1.2 "
Im nächsten Beispiel benutze ich die Variable $pwd
Beispiel 2: Provider des aktuellen Pfades bestimmen
Set-Location HKLM:\SYSTEM\CurrentControlSet
$PWD
$PWD.Provider.Name
"`nProviderwechsel`n"
Set-Location $env:windir
$PWD
$PWD.Provider.NamePath
#Ausgabe
----
HKLM:SYSTEM\CurrentControlSet
Registry
Providerwechsel
C:\Windows
FileSystem
Durch die Provider wird das Navigieren im Filesystem, in der Registry oder im Zertifikatsstore einheitlich und transparent.
Technet:
1.1.1.2 Umgebungsvariablen - Environment Variables
Technet:
Umgebungsvariablen stellen eine Reihe von Informationen des Betriebssystems und des Userprofiles direkt als Variable zur Verfügung. Darunter sind -deswegen behandle ich das Thema hier- auch etliche Pfade.
Beispiel 1: Anzeige der Umgebungsvariablen
set-location env:
get-childitem
#[system.environment]::getenvironmentvariables()
#Ausgabe
Name Value
---- -----
ALLUSERSPROFILE C:\ProgramData
APPDATA C:\Users\karl_napf\AppData\Roaming
CLIENTNAME V100WPWMK1II328
CommonProgramFiles C:\Program Files\Common Files
CommonProgramFiles(x86) C:\Program Files (x86)\Common Files
CommonProgramW6432 C:\Program Files\Common Files
COMPUTERNAME DOM1CLI01
ComSpec C:\Windows\system32\cmd.exe
DEFLOGDIR C:\ProgramData\McAfee\DesktopProtection
FP_NO_HOST_CHECK NO
HOMEDRIVE C:
HOMEPATH \Users\karl_napf
LOCALAPPDATA C:\Users\karl_napf\AppData\Local
LOGONSERVER \\DOM1DC01
NUMBER_OF_PROCESSORS 1
OS Windows_NT
Path C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbe...
PATHEXT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE AMD64
PROCESSOR_IDENTIFIER Intel64 Family 6 Model 23 Stepping 6, GenuineIntel
PROCESSOR_LEVEL 6
PROCESSOR_REVISION 1706
ProgramData C:\ProgramData
ProgramFiles C:\Program Files
ProgramFiles(x86) C:\Program Files (x86)
ProgramW6432 C:\Program Files
PSModulePath C:\Users\karl_napf\Documents\WindowsPowerShell\Modules...
PUBLIC C:\Users\Public
SESSIONNAME RDP-Tcp#0
SystemDrive C:
SystemRoot C:\Windows
TEMP C:\Users\KARL_N~1\AppData\Local\Temp
TMP C:\Users\KARL_N~1\AppData\Local\Temp
USERDNSDOMAIN DOM1.INTERN
USERDOMAIN DOM1
USERNAME Karl_napf
USERPROFILE C:\Users\karl_napf
VS90COMNTOOLS c:\Program Files (x86)\Microsoft Visual Studio 9.0\Com...
VSEDEFLOGDIR C:\ProgramData\McAfee\DesktopProtection
windir C:\Windows
windows_tracing_flags 3
windows_tracing_logfile C:\BVTBin\Tests\installpackage\csilogfile.log
Anmerkung 1 : Weitere interessante Informationen zum Betriebssystem liefert die WMI-Klasse
Anmerkung 2: Mit jeder Windowsversion kommen neue Umgebungsvariablen dazu. Dies ist eine Liste von einem Win7-Domänenclient. Unter XP sind es einige Variablen weniger
Anmerkung 3 : Manchen Umgebungsvariablen merkt man gelegentlich ihre Vergangenheit an. So sind der TEMP- und TMP Pfad oder Teile davon auf 8 Stellen gekürzt.
Falls diese Verkürzung stört, muss man auf .Net ausweichen
$outputPath =[io.path]::GetTempPath()
$outputPath
#Ausgabe
C:\Users\karl_napf\AppData\Local\Temp\
Beispiel 2: Setzen/ Ändern von Umgebungsvariablen
In Beispiel 1 haben wir alle Umgebungsvariablen des Systems angezeigt. Genaugenommen haben wir aber die Variablen aus einem userspezifischen Store und einem maschinenspezifischen Store ausgelesen. Beide Stores befinden sich in lesbarer und beschreibbarer Form in der Registry unter
HKEY_CURRENT_USER\Environment (Userspezifisch)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (Maschinenspezifisch)
Einige zusätzliche Variablen wie "Userprofile" werden dynamisch erzeugt. Alle Variablen zusammen sind "prozessspezifisch." Die Umgebungsvariablen, die nicht in der Registry stehen, sind beim nächsten Start der Powershell dann auch wieder verschwunden.
In maschinenspezifische Umgebungsvariablen kann man beispielsweise Werte während der Installation hineinsetzen, wie Standort, Inventarnummer oder auch Werte, die später bei Softwareninstallationsverfahren benötigt werden. Wenn man aus den Umgebungsvariablen den Serverfunktionstyp (Domaincontroller, Exchangeserver), oder ob der Server physikalisch oder virtuell existiert und vieles mehr, dann erleichtert dies die spätere Administration der Maschine deutlich.
#Setzen einer userspezifischen Umgebungsvariable (dauerhaft)
$name="uservariable_1"
$wert="uservalue_1"
$context="user"
[Environment]::SetEnvironmentVariable($name, $wert, $context)
#Setzen einer maschnenpezifischen Umgebungsvariable (dauerhaft)
$name="machinevariable_1"
$wert="machine_value_1"
$context="machine"
[Environment]::SetEnvironmentVariable($name, $wert, $context)
#Setzen einer prozesspezifischen Umgebungsvariable (flüchtig)
$name="processvariable_1"
$wert="process_value_1"
$context="process"
[Environment]::SetEnvironmentVariable($name, $wert, $context)
#$env:$name = $wert #alternativ
Beispiel 3: Auslesen von Umgebungsvariablen
$a=[system.environment]::GetEnvironmentVariable("windir")
#$a=$env:windir #identisch
$a
#Ausgabe
C:\Windows
Da "windir" bereits zum Prozessstart als Maschinenvariable vorhanden war, ist sie automatisch auch eine Prozessvariable. Dadurch kann sie einfach ohne Angabe des Kontextes ausgelesen werden.
Um die im vorigen Beispiel neu erzeugten User- und Machinenvariablen auszulesen, muß entweder Powershell neu gestartet werden, oder der Kontext mit angegeben werden.
$name="machinevariable_1"
$context="machine"
[Environment]::GetEnvironmentVariable($name, $context)
#Ausgabe
machine_value_1
Anmerkung: Variablen mit Prozesskontext sind sofort verfügbar, aber leider nicht Powershellsession übergreifend, sondern nur in der aktuellen Session. Man kann also nicht zwei parallele Powershellsessions geöffnet haben und Umgebungsvariablen austauschen.
1.1.1.3 GetFolderpath - Specialfolder
Neben den gezeigten Umgebungsvariablen und den "automatic variables" gibt es noch die SpecialFolder, die in der Registry unter HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders aufgelistet sind. Diese Pfade können auch über Group Policies aus dem ActiveDirectory manipuliert werden. siehe Technet:
Beispiel 1: Anzeige der Specialfolder mit Pfad
aus MSDN:
# Author: Thomas Lee
#
# Get the list of special folders
$folders = [system.Enum]::GetValues([System.Environment+SpecialFolder])
# Display these folders
"Folder Name Path"
"----------- -----------------------------------------------"
foreach ($folder in $folders) {
"{0,-22} {1,-15}" -f $folder,[System.Environment]::GetFolderPath($folder)
}
#Ausgabe
Folder Name Path
----------- -----------------------------------------------
Desktop C:\Users\karl_napf\Desktop
Programs C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Personal C:\Users\karl_napf\Documents
Personal C:\Users\karl_napf\Documents
Favorites C:\Users\karl_napf\Favorites
Startup C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
Recent C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Recent
SendTo C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\SendTo
StartMenu C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Start Menu
MyMusic C:\Users\karl_napf\Music
DesktopDirectory C:\Users\karl_napf\Desktop
MyComputer
Templates C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Templates
ApplicationData C:\Users\karl_napf\AppData\Roaming
LocalApplicationData C:\Users\karl_napf\AppData\Local
InternetCache C:\Users\karl_napf\AppData\Local\Microsoft\Windows\Temporary Internet Files
Cookies C:\Users\karl_napf\AppData\Roaming\Microsoft\Windows\Cookies
History C:\Users\karl_napf\AppData\Local\Microsoft\Windows\History
CommonApplicationData C:\ProgramData
System C:\Windows\system32
ProgramFiles C:\Program Files
MyPictures C:\Users\karl_napf\Pictures
CommonProgramFiles C:\Program Files\Common Files
Beispiel 2: Zuweisen eines Specialfolder-Pfades zu einer Variablen
$a=[Environment]::GetFolderPath("InternetCache")
$a
#Ausgabe
C:\Users\karl_napf\AppData\Local\Microsoft\Windows\Temporary Internet Files
Diese Information könnte man dazu benutzen, regelmäßig den Cache des InternetExplorers zu bereinigen, der seine Dateien hier ablegt.
1.1.2 das aktuelle Arbeitsverzeichnis und das eigene Skript
Beispiel 1a: Ändern und Abfragen des aktuellen Powershellverzeichnisses
"lokales Navigieren:"
set-location "c:\temp"
get-location #identisch mit $pwd (siehe automatic variables)
"Remote Navigieren:"
set-location "\\192.168.178.254\c$\temp"
set-location "\\dom1dc01\c$\temp"
get-location
#Ausgabe
lokales Navigieren:
Path
----
C:\temp
Remote Navigieren:
Microsoft.PowerShell.Core\FileSystem::\\dom1dc01\c$\temp
Anzeige der Aliase von get-location und set-location
siehe:
"Aliase von get-location"
get-alias -definition get-location
"`nAliase von set-location"
get-alias -definition set-location
#Ausgabe
CommandType Name Definition
----------- ---- ----------
Alias gl Get-Location
Alias pwd Get-Location
Aliase von set-location
Alias cd Set-Location
Alias chdir Set-Location
Alias sl Set-Location
Beispiel 1b: Ändern und Abfragen des aktuellen .Net Verzeichnisses
#Setzen der Arbeitsverzeichnisse
set-location "c:\temp"
[IO.Directory]::SetCurrentDirectory("c:\")
#Abfrage mit der directoryinfo-Klasse
$a=new-object system.io.directoryinfo(".")
"{0} -- {1}" -f 'system.io.directoryinfo(".")', $a.fullname
#identisch zu
$b=[system.io.directoryinfo]"."
"{0} -- {1}" -f '[system.io.directoryinfo]"."', $b.fullname
#Abfrage mit der Directory-Klasse
$c=[System.IO.Directory]::GetCurrentDirectory()
"{0} -- {1}" -f '[System.IO.Directory]::GetCurrentDirectory()', $c
#Abfrage mit PS-cmdlet
$d=get-location
"{0} -- {1}" -f 'get-location', $d
#Ausgabe
system.io.directoryinfo(".") -- c:\
[system.io.directoryinfo]"." -- c:\
[System.IO.Directory]::GetCurrentDirectory() -- c:\
get-location -- C:\temp
Man erkennt, daß die Powershell und die Klassen unter System.IO unterschiedliche Arbeitsverzeichnisse haben.
Beispiel 1c: Ändern des Arbeitsverzeichnisses und Zurücksetzen
Zu Batchzeiten erledigten diese Aufgabe die zwei Befehle pushd und popd. In der Powershell stehen beide als Aliase der cmdlets push-location und pop-location zur Verfügung. Man kann mit push-location mehrere Pfade nacheinander auf einen Standard oder einen selbstdefinierten Stack legen und mittels pop-location in umgekehrter Reihenfolge wieder aufnehmen.
Ich persönlich finde die Speicherung von Pfaden in Variablen mit aussagekräftigen Namen übersichtlicher. Aber es mag sein, daß für bestimmte Aufgaben die Flexibilität der Stacks mehr für popd/ pushd spricht.
Das Beispiel zeigt einmal den Weg über eine Variable und einmal den Weg über den Stack mittels der cmdlets push-location und pop-location. Das Ergebnis ist identisch.
"Arbeitsverzeichnis in einer Variable speichern `n"
$Ursprungspfad=get-location
"Ursprungspfad: $Ursprungspfad"
set-location c:\
"geänderter Pfad: $(get-location)"
set-location $Ursprungspfad
"zurückgeänderter Ursprungspfad $(get-location)"
"`n`nArbeitsverzeichnis im Stack speichern `n"
"Ursprungspfad=$(get-location)"
pushd #Alias von push-location
set-location c:\
"geänderter Pfad: $(get-location)"
popd #Alias von pop-location
"zurückgeänderter Ursprungspfad $(get-location)"
#Ausgabe
Arbeitsverzeichnis in einer Variable speichern
Ursprungspfad: C:\temp
geänderter Pfad: C:\
zurückgeänderter Ursprungspfad C:\temp
Arbeitsverzeichnis im Stack speichern
Ursprungspfad=C:\temp
geänderter Pfad: C:\
zurückgeänderter Ursprungspfad C:\temp
Technet:
Technet:
Beispiel 2: Ermitteln des eigenen Skriptnamens mit Pfad
Mit der "automatic variable" $MyInvocation, die ein Objekt der MyInvocation-Klasse darstellt, kommt man über die Eigenschaft InvocationName an den vollqualifizierten Namen des aufrufenden Skripts und möglicherweise weitere interessante Informationen, siehe MSDN:
$MyInvocation | select *
"Pfad dieses Skripts: $($MyInvocation.InvocationName)"
#Ausgabe
MyCommand : test.ps1
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 0
OffsetInLine : 0
HistoryId : 30
ScriptName :
Line :
PositionMessage :
InvocationName : C:\Powershell\MyScripts\test.ps1
PipelineLength : 2
PipelinePosition : 1
ExpectingInput : False
CommandOrigin : Runspace
Pfad dieses Skripts: C:\Powershell\MyScripts\test.ps1
Anmerkung 1: Ein leerer Skriptname kommt zurück, wenn das Skript noch nicht gespeichert wurde.
Anmrekung 2: In Beispiel 2 im nächsten
1.2 Powershellcmdlets zur Pfadbearbeitung
Steht der gewünschte Pfad in keiner Systemvariablen bereit, so gibt eine Handvoll cmdlets, die dann auf ihren Einsatz warten.
Beispiel 1: Anzeige der cmdlets zur Pfadbearbeitung
get-help *path*
#Ausgabe
Name Category Synopsis
---- -------- --------
Join-Path Cmdlet Kombiniert einen Pfad und einen untergeordneten Pfad zu einem Pfad. Der ...
Convert-Path Cmdlet Konvertiert einen Pfad aus einem Windows PowerShell-Pfad in einen Window...
Split-Path Cmdlet Gibt den angegebenen Teil eines Pfads zurück.
Test-Path Cmdlet Bestimmt, ob alle Elemente eines Pfads vorhanden sind.
Resolve-Path Cmdlet Löst die Platzhalterzeichen in einem Pfad auf und zeigt den Inhalt des P...
about_Path_Syntax HelpFile Beschreibt die Formate für vollständige und relative Pfadnamen in
Die meist verwendeten cmdlets sind zumindest bei mir "Split-Path". "Join-Path" und "Test-Path".
Beispiel 2: zentrales Logverzeichnis oberhalb des temp-Verzeichnisses erstellen, in dem jedes Skript ein spezifisches Logfile ablegt
Mit der Funktion "CentralLog" wird an zentraler Stelle -sofern noch nicht vorhanden- ein LogContainer erstellt. Dort erstellt ein PS-Skript, das diese Funktion aufruft, eine Logdatei aus dem Namen des aufrufenden Skriptes, sofern die Logdatei noch nicht existiert.
In diese Logdatei wird das Datum des Skriptaufrufs, sowie eine Message geschrieben und angehängt. Damit kann man sich bei Bedarf einen leichten Überblick verschaffen, wann welche Skripte ausgeführt wurden.
Es gibt anderere Szenarien, in denen es sinnvoller ist, eine bereits vorhandene Logdatei zu überschreiben, oder für jeden Skriptaufruf eine individuelle neue Logdatei zu erstellen, deren Name sich beispielsweise aus dem Scriptnamen und dem aktuellen Datum mit Uhrzeit zusammensetzt.
Hier gehts mir aber um ein sinnvolles Beispiel für den Einsatz einiger "path-cmdlets", wie split-path, join-path und test-path.
Function CentralLog{
param($funLogname,$funMessage)
$LogContainer="PSLogs"
#Schritt 1
$funTempPath =[io.path]::GetTempPath()
$funParentTempPath=split-path $funTempPath -parent
$funPSLogPath=join-path -path $funParentTempPath -ChildPath $LogContainer
#Schritt 2
$a=Test-Path -path $funPSLogPath
if ($a -eq $false){
New-Item -path $funPSLogPath -type directory
"Das Verzeichnis $funPSLogPath wurde angelegt"
}else{
"Verzeichnis $funPSLogPath existiert schon"
}
#Schritt 3
$funoutpath=$funPSLogpath+"\"+$funLogname
$funDateTime=get-date -f "dd-MM-yyyy HH:mm:ss"
out-file -filepath $funOutPath -inputobject ($funDatetime+": "+$funMessage) -append
}
#Schritt 0
$skriptname=$myinvocation.mycommand.name
$Logname = ($skriptname -split "\.")[0]
$Logname=$Logname+".log"
$Message="Skript erfolgreich aufgerufen"
CentralLog $logname $Message
Erklärung:
Schritt 0:
$skriptname=$myinvocation.mycommand.name
$myinvocation ist eine der "automatic variables", die ich in
$Logname = ($skriptname -split "\.")[0]
Abtrennen der Dateierweiterung .ps1 vom übrigen Skriptnamen
CentralLog $logname $Message
Funktionsaufruf: die Parameter sind durch Leerzeichen getrennt
Schritt 1:
$funTempPath =[io.path]::GetTempPath()
Einer der festgelegten Pfade die ich im
$funParentTempPath=split-path $funTempPath -parent
$funPSLogPath=join-path -path $funParentTempPath -ChildPath $LogContainer
Schritt 2:
Prüfen ob das Zielverzeichnis vorhanden ist. Falls nicht, wird es angelegt
Schritt 3:
Datum und Message in die Textdatei schreiben
Anmerkung: Natürlich kann man sich diese Funktion in jedes seiner Skripte hineinkopieren und dann verwenden. Powershell bietet aber auch die Möglichkeit, diese Funktion in einer einzigen Skriptdatei (Bibliothek) zentral abzulegen und diese als Include-File zu importieren. Das kann die Wartung dieser Funktion deutlich vereinfachen.
1.3 Pfade mit Sonderzeichen
Die Navigation im Filesystem erfolgt über den Fileprovider meist ohne große Anstrengungen. Ein bischen knifflig kann es bei der Verwendung von Sonderzeichen im Ordner- oder Dateinamen werden. Entweder hat man Glück und die Powershellentwickler haben das notwendige cmdlet mit dem Parameter " "-literalpath" ausgestattet, der alle Zeichen und Sonderzeichen so nimmt wie sie sind. Falls das cmdlet diesen Parameter nicht bereitstellt, muß man entweder den Weg über eine .Net Klasse gehen oder mit dem cmdlet new-PSDrive ein neues PSDrive anlegen. Die folgenden Beispiele zeigen die Wege
Beispiel 1: Navigieren zu einem Pfad mit dem Parameter "-Literalpath"
Das cmdlet set-location besitzt den Positionsparameter -literalpath. So ist man in der angenehmen Situation einfach diesen Parameter benutzen zu können und Sonderzeichen wie "[]" werden ohne Schwierigkeiten akzeptiert.
#set-location c:\temp\test[1] #würde einen Fehler produzieren
set-location -literalpath c:\temp\test[1]
get-location
#Ausgabe
c:\temp\test[1]
Der Wert des LiteralPath-Parameters wird genau so verwendet, wie er eingegeben wurde. Es werden keine Zeichen als Platzhalter interpretiert. Wenn der Pfad Escapezeichen enthält, müssen Sie ihn in einfache Anführungszeichen einschließen. Einfache Anführungszeichen veranlassen Windows PowerShell, Zeichen nicht als Escapesequenzen zu interpretieren. (aus der Onlinehilfe zu Set-Location)
Beispiel 2a: Workaround mit .Net für das cmdlet "get-acl", das kein -Literalpath enthält
#get-acl c:\temp\test[1] | select * # liefert nichts zurück
([io.directoryinfo]"C:\Temp\Test[1]").getaccesscontrol() | select * # liefert die Accesslisten
#Ausgabe gekürzt
AccessToString : VORDEFINIERT\Administratoren Allow FullControl
VORDEFINIERT\Administratoren Allow 268435456
....
Beispiel 2b: Workaround mit dem cmdlet New-PSdrive für das cmdlet "get-acl", das kein -Literalpath enthält
remove-psdrive -name myTest -EA 0 #Falls myTest schon vorhanden ist, gibt es sonst eine Fehlermeldung
new-psdrive -name myTest -psprovider filesystem -root "c:\temp\test[1]"
(get-acl myTest:).access
#Ausgabe gekürzt
AccessToString : VORDEFINIERT\Administratoren Allow FullControl
VORDEFINIERT\Administratoren Allow 268435456
....
Für das cmdlet get-acl steht kein Parameter "-LiteralPath" zur Verfügung. Daher muß man entweder den kleinen Umweg über eine geeignete .Net Klasse gehen (Fündig wird man für Fileoperationen meist in den Klassen des System.IO - Namespaces. siehe MSDN:
Mit deutschen Sonderzeichen wie "äöüß" kommt Powershell übrigens ohne zu Zucken und ohne -literalpath zurecht.