All posts tagged Get-Member

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