Drücke "Enter", um den Text zu überspringen.

Kategorie: PowerShell

Windows Server / Client: Alle geplanten Tasks per PowerShell auslesen

Insbesondere auf Servern kann es schnell vorkommen, dass hier sehr viele Gepante Tasks („Aufgaben“) vorhanden sind, die aber über viele Ordner im Taskplaner verteilt sind:

TaskPlaner

Wenn man nun einen bestimmten Task sucht oder einfach wissen möchte, was so an Aufgaben alles geplant ist, dann ist die GUI hier leider keine große Hilfe. Aber mit der PowerShell bekommt man schnell das Gewünscht:

1
Get-ScheduledTask | Select URI,@{n="LastRun";e={($_ | Get-ScheduledTaskInfo).LastRunTime}} | Sort-Object LastRun

TaskPlaner2

Viel Spaß damit!

Schreibe einen Kommentar...

Hyper-V-Server / Windows Server Core: Treiber via PowerShell installieren

Wer einen Windows Server 2012 R2 als Core-Server oder den kostenfreien Hyper-V-Server 2012 R2 einsetzt, dem könnte folgendes Problem begegnen: Auf dem Server selber gibt es bekanntlich keine GUI und demnach auch keinen Gerätemanager. Und seit 2012 R2 lässt sich dieser auch nicht remote von einem grafischen Server aus ansprechen!

Was nun also tun, wenn man Treiber installieren/aktualisieren/entfernen will? Dazu möchte ich hier einige Kommandos als Hilfestellung zusammentragen:

 

Installation aller Treiber des aktuellen Verzeichnisses in das Treiber-Repository:

Get-ChildItem -Recurse -Filter *.inf | Select-Object FullName | ForEach-Object {pnputil -a $_.FullName}

Installation eines bestimmten Treibers:

pnputil.exe -i -a C:\Pfad\zum\Treiber.inf

(ACHTUNG: Installiert diesen Treiber für alle „passenden“ Geräte!)

Auflisten aller Treiber im Repository (3rd Party):

pnputil.exe -e

Entfernen eines Treibers aus dem Repository:

pnputil.exe -d oemX.inf (Name der INF-Datei über pnputil -e)

Entfernen aller Treiber aus dem Repository:

1..40 | ForEach-Object {pnputil.exe -d „oem$_.inf“} (Die Zahl 40 muss ausgetauscht werden durch die höchste Zahl aus pnputil -e)

Ermitteln der Hardware-ID der Geräte einer bestimmten Geräteklasse (hier: Netzwerkkarten)

devcon.exe listclass net

Anzeigen des von einem Gerät benutzten Treibers:

devcon.exe driverfiles „@PCI\VEN_8086&DEV_10D3&SUBSYS_040D15D9&REV_00\4&60B4255&0&00E4“

Installation eines bestimmten Treibers für ein bestimmtes Gerät:

devcon.exe /r install C:\Pfad\zum\Treiber.inf „@PCI\VEN_8086&DEV_10D3&SUBSYS_040D15D9&REV_00\4&60B4255&0&00E4“

Entfernen eines konkreten Gerätes (nicht nur der Treiber!):

devcon.exe /r remove „@PCI\VEN_8086&DEV_10D3&SUBSYS_040D15D9&REV_00\4&60B4255&0&00E4“

Nach neuen Geräten suchen:

devcon.exe rescan

 

Für einige Varianten ist DevCon.exe nötig. Siehe dazu hier:

https://msdn.microsoft.com/de-de/library/windows/hardware/ff544707(v=vs.85).aspx

http://www.wintotal.de/tipparchiv/?id=2075

Der Artikel wird künftig weiter ergänzt…

Schreibe einen Kommentar...

Hyper-V: PowerShell-Skript um nicht benutzte bzw. verwaiste VHD / VHDX Dateien zu finden

Auf einem Hyper-V System sammeln sich über die Jahre einige virtuelle Festplatten-Dateien im VHD- bzw. VHDX-Format an. Aber werden diese wirklich noch alle gebraucht? Das ist häufig schwer zu sagen, da insbesondere durch das Löschen von VMs nur deren Beschreibungs-Dateien, nicht aber die Festplatten gelöscht werden. Ähnliches kann passieren, wenn man die Replikation einer VM beendet.

Um nun diejenigen VHDs, die von keiner VM mehr genutzt werden, zu finden, habe ich ein Skript geschrieben. Dieses berücksichtigt auch, dass sich mehrere VHD/VHDX Dateien in einer Differenzierungskette befinden könnten.

Das Skript sowie eine Beschreibung findet ihr hier:

https://gallery.technet.microsoft.com/scriptcenter/Get-AbandonedVHDs-V1-to-8bfb28d9

Dem Skript kann neben einem oder mehreren Suchordnern auch u.a. eine Option übergeben werden, die direkt die nicht benötigten Dateien löscht. Das ist aber nicht ganz ungefährlich, ggf. haben die VHDs ja eine andere Funktion und sind gar nicht für Hyper-V. Denkbar wäre z.B., dass ein iSCSI-Software-Target im Einsatz ist, oder aber auch die Windows Server Sicherung.

script

Schreibe einen Kommentar...

System Center Configuration Manager: Site Code eines Clients auslesen

Um den Site Code (Standortcode) eines SCCM Clients auszulesen, kann man WMI verwenden. Ich habe dafür ein kleines PowerShell Script geschrieben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<# .Synopsis Returns the Site Code of a SCCM Client as a String .DESCRIPTION Queries a given computer using WMI and returns its site code for System Center Configuration Manager (Tested on 2012 R2 and 1511) .EXAMPLE Get-SMSSiteCode -MachineName PC1 Get's the site code of the Computer named PC1 #>
 
Function Get-SMSSiteCode
{
    Param(
        # The Computername of the machine that you want to query for it's SCCM Site Code
        [Parameter(Mandatory=$true)]
        [string]$MachineName
    )
 
    Return (Get-WmiObject -ComputerName $MachineName `
                          -Namespace "root\CCM" `
                          -Class sms_authority `
           ).Name.TrimStart("SMS:")
}

Downloaden könnt ihr das Skript hier!

Schreibe einen Kommentar...

SCCM 2012 R2 – E-Mails für Softwareanforderungen (Umfangreicher)

In einem älteren Artikel habe ich mich schon einmal mit der Frage beschäftigt, wie man neue Genehmigungsanforderungen für Software (Anwendungen) in System Center Configuration Manager per Mail an den Admin melden kann.

Was aber, wenn nicht (nur) der Admin eine Mail erhalten soll, sondern z.B. auch der Vorgesetzte des jeweiligen Benutzers, der die Software angefordert hat? Und was ist mit dem Benutzer selbst? Es wäre doch gut, wenn dieser bei Genehmigung/Ablehnung auch informiert wird?!

Das Ganze lässt sich natürlich wunderbar per PowerShell lösen. Damit nun aber nicht ein Prozess o.ä. permanent laufen muss, wäre es sinnvoll, dieses Skript z.B. nur 1x pro Stunde (über den Taskplaner) automatisch laufen zu lassen. In sofern interessieren in jedem Durchlauf des Skriptes auch nur diejenigen Anforderungen, die

  • In der letzten Stunde neu erstellt wurden (“CurrentState” ist 1)
  • In der letzten Stunde abgelehnt wurden (“CurrentState” ist 3)
  • In der letzten Stunde genehmigt wurden (“CurrentState” ist 4)

Aus dieser Überlegung und der Tatsache, dass sich sowohl der Vorgesetzte als auch die Mailadressen aus dem AD auslesen lassen, resultierte dieses einfache Script (Es ist nicht wirklich “schön” geschrieben, aber zumindest rudimentär kommentiert. Für einen produktiven Einsatz wird man es ohnehin nochmal an die eigenen Bedürfnisse anpassen müssen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
$SiteName = "PS0"
$SiteName = "PS0"
$AdminsMail = "helpdesk@kurs.intern"
$Mailserver = "mail.kurs.intern"
$Absender = "SCCM Application Request Admin"
 
$MailAnAdmins = $True
$MailAnVorgesetzten = $True
 
function Send-MyEmail
{
 
    Param(
        [string]$Sender,
        [string]$Empfaenger,
        [string]$Mailserver,
        [string]$Betreff,
        [string]$Mailtext,
        [Switch]$TestOnly
    )
 
    try{
        If(-not $TestOnly)
        {
            Send-MailMessage -From $Sender -To $Empfaenger -Subject $Betreff -Body $Mailtext 
                -SmtpServer $Mailserver -ErrorAction Stop
        }
        else
        {
            Write-Host "E-Mail für '$Empfaenger' von '$Sender' über den Mailserver '$MailServer' `n
                        mit dem Betreff '$Betreff' und dem Text:"
            Write-Host "$Mailtext `n"
 
        }
    }
    catch{
        Write-Debug "Fehler beim Versand der E-Mail über den Mailserver $SmtpServer!"
    }
 
}
 
# PS-Modul für AD lasen
Import-Module ActiveDirectory
 
# PS-Module für SCCM laden
Import-Module "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
Set-Location "$($SiteName):\"
 
# ApprovalRequests auslesen, die sich in der letzten Stunde geändert haben 
# (Script soll stündlich laufen)
$OffeneRequests = Get-CMApprovalRequest | Where {$_.LastModifiedDate -gt (Get-Date).AddHours(-1)}
 
ForEach($Request in $OffeneRequests)
{
    # Anfordernder Benutzer
    $Benutzer = $Request.User
    $BenutzerLogin = Get-ADUser $($Benutzer.Substring(($Benutzer.IndexOf("\")+1),
                                                       $Benutzer.Length-$Benutzer.IndexOf("\")-1))
    $BenutzerName = ($BenutzerLogin | Get-ADUser).Name
 
    # Anwendung um die es geht
    $Anwendung = $Request.Application
 
    # Neue Anforderung
    If($Request.CurrentState -eq 1)
    {
        # E-Mail an Admin / Helpdeks senden
        If($MailAnAdmins)
        {
            Send-MyEmail -Sender $Absender -Empfaenger $AdminsMail -Mailserver $Mailserver 
                -Betreff "Neue Softwareanforderung von $BenutzerName" -Mailtext "Blabla..." 
                -TestOnly
        }
 
        # E-Mail an Vorgesetzten senden
        If($MailAnVorgesetzten)
        {
            # Vorgesetzter des anfordernden Benutzers
            $Vorgesetzter =  ($BenutzerLogin | Get-ADObject -Properties Manager).Manager | Get-ADUser
            $VorgesetzterMail = (Get-ADObject $Vorgesetzter -Properties mail).Mail
 
            Send-MyEmail -Sender $Absender -Empfaenger $VorgesetzterMail -Mailserver $Mailserver 
                -Betreff "Neue Softwareanforderung von $BenutzerName" -Mailtext "Blabla..." 
                -TestOnly
        }
    }
 
    # Anforderung wurde durch einen Administrator im SCCM genehmigt
    If($Request.CurrentState -eq 4)
    {
 
        # Mail an den anfordernden User senden
        $BenutzerMail = (Get-ADObject $BenutzerLogin -Properties mail).Mail
 
        Send-MyEmail -Sender $Absender -Empfaenger $BenutzerMail -Mailserver $Mailserver 
            -Betreff "Ihre Softwareanforderung für $Anwendung wurde genehmigt" -Mailtext "Blabla..." 
            -TestOnly
    }
 
    # Anforderung wurde durch einen Administrator im SCCM abgelehnt
    If($Request.CurrentState -eq 3)
    {
 
        # Mail an den anfordernden User senden
        $BenutzerMail = (Get-ADObject $BenutzerLogin -Properties mail).Mail
 
        Send-MyEmail -Sender $Absender -Empfaenger $BenutzerMail -Mailserver $Mailserver 
            -Betreff "Ihre Softwareanforderung für $Anwendung wurde abgelehnt" -Mailtext "Blabla..." 
            -TestOnly
    }
}

In der Ausführung sieht das dann so aus:

Approval2

Approval1

Ausführen lässt sich das Skript via Taskplaner dann beispielsweise mit:

powershell.exe -ExecutionPolicy Bypass -file „SCCMMailsFuerApprovalRequests.ps1“

Das Skript lässt sich auch hier herunterladen:

Downloadlink über OneDrive

Schreibe einen Kommentar...

Microsoft Technical Summit 2015 – Die Video-Aufzeichnungen sind verfügbar!

Wer die Sessions des Summits noch einmal in Ruhe zuhause ansehen will oder gar nicht beim Summit dabei sein konnte, aber sich für die Inhalte interessiert, hat jetzt die Möglichkeit, die Videos und Unterlagen herunterzuladen.

Unter http://www.microsoft.com/germany/technical-summit/nachlese-2015.aspx sind alle Sessions der beiden tage mit den jeweiligen Infos sowie den Unterlagen und Videos aufgelistet. Hier bekommt man die Videos in mittlerer Qualität.

Unter https://channel9.msdn.com/Events/microsoft-techncial-summit/Technical-Summit-2015-The-Next-Level stehen alle Videos in 3 Qualitätsstufen zur Verfügung – und auch als MP3 Podcast.

Ich habe ein PowerShell-Script geschrieben, was den Download aller Videos in einer benutzerdefinierten Qualitätsstufe ohne großen Aufwand erledigt:

MSTS_Videos

Das komplette Script könnt ihr hier herunterladen:

http://1drv.ms/1TelkeJ

Der Aufruf erfolgt dann in etwa so:

.\Get-MSTS15Content.ps1 -OutFolder D:\MSTS15 -VideoQuality Low

Viel Spaß damit!

2 Comments

Microsoft Technical Summit 2015: Meine Session zum Thema PowerShell 4.0 und 5.0

Für all diejenigen, die in meiner Session zum Thema “Deep Dive – Neuerungen in PowerShell 4.0 und 5.0” auf dem Microsoft Technical Summit 2015 in Darmstadt gesessen haben – und auch für die, die es nicht geschafft haben – stelle ich hier meine Folien und Beispiel-Skripte bereit. Sobald die Video-Aufzeichnungen verfügbar sind, werde ich diese ebenfalls hier veröffentlichen…

PowerShell Deep Dive – Neuerungen in PowerShell 4.0 und 5.0 - Normal

Downloads:

PowerPoint-Slide-Deck

PowerShell-Skripte und Beispiele

Schreibe einen Kommentar...

PowerShell DSC meldet Fehler bzgl. MSFT_RoleResource

Wenn beim Versuch, PowerShell DSC Konfigurationen von einem Windows Server 2016 als Pull-Server auf andere Server der selben Generation zu schicken, neuere Ressourcen verwendet werden, dann kann u.U. folgender Fehler auftreten:

PS_DSC_MSFT

Fehlermeldung nochmal vollständig:

“The PowerShell DSC resource MSFT_RoleResource from module <PSDesiredStateConfiguration,1.0> does not exist at the PowerShell module path nor is it registered as a WMI DSC resource.”

Grund ist ein unterschiedlicher Patch-Stand zwischen den einzelnen Servern. Abhilfe schafft also ein einspielen der entsprechenden Patches.

Schreibe einen Kommentar...

SCVMM 2012 R2: Konsole stürzt nach dem Hinzufügen einer Benutzerdefinierten Eigenschaft (“Custom Property”) ab

Heute hatte ich folgenden Effekt:

Nach dem Erstellen einer neuen “Custom Property” mit dem Namen “HDD-Typ SSD,SAS,SATA” (Sonderzeichen wie Klammern und Schrägstriche sind nicht zulässig und werden von der GUI abgefangen) stürzt die SCVMM Konsole sofort ab und lässt sich auch nicht wieder starten.

SCVMM_CustomProp0SCVMM_CustomProp0a

Der erste Fehler hat den Ereignisnamen “CLR20r3” an der “VmmAdminUI.exe”. Vermutlich gibt es für dieses Problem mittlerweile einen Patch, aber die verwendete Umgebung war nicht komplett gepatcht. Also musste eine Alternative her. Naheliegend war das Löschen der neu angelegten Eigenschaft, aber dies musste ohne GUI erfolgen (diese ließ sich wegen des Crashes ja nicht starten). Also bleibt nur die PowerShell…

Zunächst habe ich mit “Get-SCCustomProperty” nach der betreffenden Eigenschaft gesucht:

SCVMM_CustomProp0b

Der komplette Aufruf:

Get-SCCustomProperty | Where Name -NotLike "Custom*"

Danach kann man diese mit “Remove-SCCustomProperty” löschen:

SCVMM_CustomProp0c

Der komplette Aufruf:

Get-SCCustomProperty -Name "HDD-Typ SSD, SAS, SATA" | Remove-SCCustomProperty

Danach startet auch die Konsole wieder!

Hinweis: Zur Nutzung der SC-Kommandos muss das entsprechende Modul geladen sein. Dies geht am einfachsten, in dem man auf dem SCVMM-Server selbst die “Virtual Maschine Manager Command Shell” startet:

SCVMM_CustomProp3

Schreibe einen Kommentar...

Windows 10: VPN-Verbindungen nutzen immer Remote-Gateway

Unter früheren Windows-Versionen konnte man bei VPN-Verbindungen noch den gesamten IPv4-Teil konfigurieren. Dort gab es eine Option “Standardgateway für das Remotenetzwerk verwenden”, die man abschalten konnte:

43e8230241a19524c77c2973e1ce137b

Standardmäßig war/ist diese Option eingeschaltet und sorgt dafür, dass SÄMTLICHER Datenverkehr über das Remote-Netz geleitet wird, auch das, was eigentlich “DIREKT” ins Internet gehen könnte. Der Vorteil dabei ist, dass der Traffic vom eigenen Endgerät bis zum Firmennetzwerk verschlüsselt ist, was insbesondere dann nützlich ist, wenn man in einem Internetcafe oder Hotel-WLAN sitzt und nicht klar ist, wer den Verkehr mithören kann.

Will man nun auf einem Windows 10 Client dieses Verhalten ändern – also erreichen, dass nur Traffic, der für das Remote-Netzwerk gedacht ist, über VPN geht, der Rest direkt ins Internet, müsste man diesen Haken entfernen, was bei Windows 10 nicht mehr geht, da sich die IPv4-Optionen der VPN-Verbindung nicht mehr öffnen lassen.

Was man aber tun kann, ist dieses Verhalten mit Hilfe der PowerShell herbeizuführen, und zwar mit diesem Aufruf:

123

Damit wird für alle VPN-Verbindungen das “Split-Tunneling” aktiviert, was eben diesem Haken entspricht.

Hier der Aufruf nochmal zum direkt Kopieren:

1
 Get-VpnConnection | Set-VpnConnection -SplitTunneling $True

456

Schreibe einen Kommentar...