Zum Inhalt

Kategorie: Windows

PowerShell: Windows Aufgabenplanung exportieren

Verwendet man die Windows Aufgabenplanung für viele Aufgaben, so macht es in jedem Fall Sinn die einzelnen Aufgaben auch zu sichern, damit man diese im Bedarfsfall auch einfach wieder importieren kann. Das folgende PowerShell Skript exportiert die Aufgaben.

$sch = New-Object -ComObject("Schedule.Service")
$sch.Connect("localhost")
$tasks = $sch.GetFolder("\").GetTasks(0)
 
$outfile_temp = "C:\PoSh\Save_ScheduledTasks\{0}.xml";
 
$tasks | %{
    $xml = $_.Xml
    $task_name = $_.Name
    $outfile = $outfile_temp -f $task_name
    $xml | Out-File $outfile 
}

Das Skript exportiert alle Aufgaben des lokalen Rechner (»localhost«) aus dem Hauptordner der Aufgabenplanung in das Verzeichnis, das mittels der Variablen »$outfile_temp« definiert wird.

rsync für Windows

Wirklich praktisch ist die Möglichkeit, dass man rsync mittels Cygwin auch unter Windows nutzen kann. Allerdings hat dies den Nachteil, dass man zunächst eine vollständige Cygwin Installation vornehmen muss. Einfacher geht dies mittels der folgenden Lösung: rsync für Windows.
Das Paket muss entpackt werden, die vorhandene cmd-Datei an die eigenen Gegebenheiten angepasst und schon kann man auf eine einfache Weise „Backups“ von Dateien erstellen.

Nur für den Fall, dass die eigentliche Herkunftsseite offline gehen sollte, habe ich das Paket von dort hier auch hochgeladen.
rsync.zip

UPDATES:
2016/01/31: Link zur Projektseite aufgrund von Kommentar angepasst.

PsTools

Die PsTools sind eine sehr gute Hilfe, wenn man bestimmte Dinge automatisieren, vereinfachen und weiteres möchte. Gerade für mich im Einsatz ist PsExec mit dem man auf einem Remotesystem einen Befehl ausführen kann.

PsTools

Prozess beenden

Will man unter Windows einen Dienst/Prozess bspw. mittels einer Batchdatei beenden kann man dies mittels dem Kommandozeilenprogramm »taskkill.exe« erledigen. Das Programm an sich ist sehr einfach zu verwenden. Ein großer Vorteil ist, dass man auch Kombinationen wie bspw. den Prozessnamen und den ausführenden Benutzer prüfen kann. Sinnvoll ist das z.B. wenn man einen Prozess mehrfach ausführt aber unter verschiedenen Benutzeraccounts.

taskkill /F /IM process.exe /FI "USERNAME eq serviceaccount-user"

Als Filter (Schalter »/FI«) kann man verschiedene Parameter verwenden, wie man der folgenden Aufstellung entnehmen kann.

    Filtername    Gültige Operatoren        Gültige Werte
    ----------    ------------------        -------------------------
    STATUS        eq, ne                    RUNNING |
                                            NOT RESPONDING | UNKNOWN
    IMAGENAME     eq, ne                    Abbildname
    PID           eq, ne, gt, lt, ge, le    Prozesskennungswert
    SESSION       eq, ne, gt, lt, ge, le    Sitzungsnummer
    CPUTIME       eq, ne, gt, lt, ge, le    CPU-Zeit im Format:
                                            hh:mm:ss.
                                            hh - Stunden,
                                            mm - Minuten, ss - Sekunden
    MEMUSAGE      eq, ne, gt, lt, ge, le    Speicherverwendung (KB)
    USERNAME      eq, ne                    Benutzername im Format:
                                            [Domäne]\Benutzername
    MODULES       eq, ne                    DLL-Name
    SERVICES      eq, ne                    Dienstname
    WINDOWTITLE   eq, ne                    Fenstertitel

Ereignisprotokollierung beim Herunterfahren anzeigen

Im Standard wird unter Windows 7 der Dialog beim Herunterfahren nicht angezeigt, in dem man einen Grund angeben muss, warum der Rechner heruntergefahren wird. Viele werden diesen Dialog von Windows Server Betriebssystemen kennen. Will man diesen auch unter Windows 7 anzeigen, so ist dies ganz einfach zu realisieren.

Bei dieser Einstellung handelt es sich um eine lokale Gruppenrichtlinie, die über den Gruppenrichtlinien-Editor verändert werden kann. Hierzu ruft man »gpedit.msc« auf.

Im Gruppenrichtlinien-Editor muss man die Einstellung »Ereignisprotokollierung für Herunterfahren anzeigen« auf »Aktiviert« ändern.

Beim nächsten Versuch den Computer herunterzufahren wird der entsprechende Dialog anzeigt.

PowerShell: E-Mail an mehrere Empfänger verschicken

Will man, wie hier beschrieben, eine E-Mail verschicken und dies an mehrere Empfänger, so kann man diese auch in einer „externen“ Datei ablegen. Sinnvoll ist dies bspw. wenn ein Script im Fehlerfall bestimmte Empfänger benachrichtigen soll und man diese Empfänger nicht codiert im PowerShell Skript hinterlegen will.
Zu diesem Zweck legt man die E-Mail Adressen der Empfänger einfach zeilenweise in einer Textdatei ab und lässt diese dann vom PowerShell Skript einlesen und übergibt das Ergebnis an den Send-MailMessage Befehl.

1
2
3
4
5
6
7
8
9
10
11
12
13
$i = 1;
$Recip = "";
$RecipientFile = (Get-Content C:\Temp\test.txt);
foreach ($Recipient in $RecipientFile)
{
	if ($i -gt 1)
	{ $Recip = $Recip + "," }
	$Recip = $Recip + $Recipient 
	$i++;
}
$Recip = $Recip.TrimEnd();
$toAddress = $Recip.Split(",")
Send-MailMessage -To $toAddress -From sender@example.com -Subject MultipleRecipients -SmtpServer smtp@example.com

PowerShell: E-Mail mit Sonderzeichen verschicken

Will man mittels PowerShell eine E-Mail versenden, so kann man hierfür die eingebaute Funktion »Send-MailMessage« verwenden. Will man hierbei auch Sonderzeichen im Text der Email verwenden, so muss man die Option »-Encoding« anhängen und den Zeichensatz UTF8 definieren. Ein einfaches Beispiel hierfür sieht wie folgt aus.

Send-MailMessage -Body 'Ein paar Sonderzeichen: äöüß' -Encoding ([System.Text.Encoding]::UTF8) -To receipient@example.com -From sender@example.com -SmtpServer smtp@example.com -Subject TestSubject

Muss man weitere Parameter übergeben, wie bspw. eine Authentifizierung gegenüber dem SMTP-Server, so findet man diese bei Microsoft im TechNet.

Send-MailMessage @ Microsoft TechNet

Shortcut für neue Debug-Instanz in Visual Studio

Wenn man in Visual Studio mehrere Projekte in einer Projektmappe hat, so hat man das Problem, dass immer nur ein Projekt als Startprojekt definiert sein kann. Dies hat zur Folge, dass, auch wenn man eine Datei eines anderen Projekts bearbeitet, bei Ausführung über »Debuggen starten« immer das aktuell definierte Startprojekt gestartet wird.
Genau aus diesem Grund wäre es schön, wenn es eine Möglichkeit gibt, mit der man immer das Projekt starten kann, in dem man auch gerade eine Datei bearbeitet.

Genau für diesen Zweck muss man einfach einen neuen Shortcut in Visual Studio definieren. Der entsprechende Eintrag in den Optionen heißt »KlassenansichtKontextmenüs.KlassenansichtProjekt.Debuggen.NeueInstanzstarten«, wie man auch im folgenden Screenshot sehen kann.

In meinem vorliegenden Beispiel habe ich hierfür einfach den Shortcut »Strg + Umschalt + Alt + F5« gesetzt. Somit kann ich immer das Projekt starten, in dem ich gerade eine Datei editiere. Unschön hierbei ist, dass wenn man ein Klassenbibliothek bearbeitet, man diese natürlich nicht ausführen kann. Somit passiert nichts bzw. man erhält dann eine Fehlermeldung , dass eine Klassenbibliothek nicht direkt ausgeführt werden.
Hierfür gibt es auch noch eine Lösung. Diese ist allerdings nur mittels eines Makro zu realisieren. Mir persönlich zu aufwendig aber vielleicht für den oder anderen dennoch interessant. Daher hier der Link zur Lösung: Visual Studio -> Debug – Start new instance shortcut

Update vom 08.08.2013:
In Visual Studio 2012 hat sich das Vorgehen nicht geändert. Falls jemand in einer englischen Installation auf der Suche nach dem passenden Kommando ist, so lautet dieses »ClassViewContextMenus.ClassViewProject.Debug.Startnewinstance«.

Google Chrome mit Proxy verwenden

Grundsätzlich verwendet Google Chrome unter Windows die gleichen Netzwerkeinstellungen, die auch der Internet Explorer verwendet. Wenn man also nur für Chrome einen Proxy einstellen möchte, der für Chrome gilt, für den IE aber nicht, so ist man mit Bordmitteln aufgeschmissen.

Die Möglichkeit besteht aber trotzdem. Man kann hierzu Chrome mit einem Parameter von der Kommandozeile aus starten. In der Regel liegt die ausführbaren Dateien von Chrome im Verzeichnis »C:\Users\Username\AppData\Local\Google\Chrome\Application\«

chrome.exe --proxy-server="localhost:1111"

Führt man das oben stehende Beispiel aus, so würde Chrome versuchen die Verbindungen über einen Proxy auf »localhost« mit Port »1111« durchzuführen.

Will man einen SOCKS-Proxy verwenden, so kann man dies wie im folgenden Beispiel machen:

chrome.exe --proxy-server="socks5://localhost:4444"

Quelle: How do I set Chrome up with my proxy?

Datei mittels PowerShell aktualisieren/kopieren

Will man eine Datei von einem Verzeichnis automatisch in anderes Verzeichnis kopieren, so kann man dies unter Windows relativ einfach mit einer Batch-Datei und der Aufgabenplanung erledigen.
Will man allerdings die Datei nur kopieren, wenn die Datei im Quellverzeichnis neuer ist als die Datei im Zielverzeichnis so geht dies mit einer Batch-Datei schon nicht mehr so einfach.

Zu diesem Zweck kann man sich aber ein PowerShell Skript schreiben, dass genau diese Funktionalität abbildet. Falls man bisher noch keine PowerShell Skripte auf seinem Rechner eingesetzt hat, muss man zunächst die sogenannte »ExecutionPolicy« ändern. Weitere Infos hierzu kann man dem folgenden Link entnehmen: Running Scripts From Within Windows PowerShell.
Abgekürtzt reicht es aus, wenn man eine Instanz der PowerShell als Administrator (also als Administrator ausführen) startet und den folgenden Befehl ausführt:

Set-ExecutionPolicy Unrestricted

Die Abfrage einfach mit »J« beantworten.

Auf einem Testsystem kann man diesen Befehl so verwenden, auf einem produktiven System (bspw. Server) sollte man dies nicht einsetzen, wenn man nicht weiß, welche Konsequenzen hieraus resultieren können.

$BackEndDir = "C:\PowerShellCopy\Backend\"
$BackEndFile = "ImportantInformation.txt"
$FrontEndDir = "C:\PowerShellCopy\Frontend\"
 
if ( !$BackEndDir.EndsWith("\") )
{ $BackEndDir = $BackEndDir + "\" }
if ( !$FrontEndDir.EndsWith("\") )
{ $FrontEndDir = $FrontEndDir + "\" }
 
$BackFile = $BackEndDir + $BackEndFile
$FrontFile = $FrontEndDir + $BackEndFile
 
if ( !(Test-Path $BackFile) )
{
    Write-Host("Datei im Backend ist nicht vorhanden")
    return
}
 
$objBackFile = get-item $BackFile
$objBackFileLWT = [datetime]$objBackFile.LastWriteTimeUTC
 
Write-Host ("BackEndDatei: " + $objBackFileLWT)
 
If ( (Test-Path $FrontFile) )
{
    echo "Datei vorhanden"
    $objFrontFile = get-item $FrontFile
    $objFrontFileLWT = [datetime]$objFrontFile.LastWriteTimeUTC
    Write-Host ("FrontEndDatei: " + $objFrontFileLWT)
    if ($objBackFileLWT -gt $objFrontFileLWT)
    {
        Write-Host ("Datei wird im FrontEnd aktualisiert")
        Copy-Item $BackFile $FrontEndDir
    }
    else
    {
        Write-Host ("Datei im FrontEnd ist gleich alt bzw. aktueller")
    }
}
Else
{
    Write-Host ("Datei nicht vorhanden")
}

Für die eigene Verwendung müssen im Grunde nur noch die Verzeichnispfade und der Dateiname in den ersten drei Zeilen angepast werden.

Führt man dann dieses PowerShell Skript mittels der Aufgabenplanung aus, so wird die Datei aus dem Backend-Verzeichnis immer dann in das Frontend-Verzeichnis kopiert, nur wenn diese auch wirklich aktueller ist. Somit ist man immer auf dem aktuellsten Stand, verhindert aber unnötige Kopieraktionen, was gerade bei großen Dateien ein Vorteil sein kann.

Quellen:
Converting the FileSystemObject’s FileExists Method
Using the Copy-Item Cmdlet
Verwenden des Cmdlet „Set-ExecutionPolicy“
Windows PowerShell Tip: The String’s the Thing