DNS Konfiguration aller Active Directory Directory Services (AD DS) Computer ändern

eingetragen in: Core, Powershell, Windows | 0

Die Aufgabe hier war letztlich verhältnismäßig simpel:

Ändere (ersetze) die bisherige DNS Server Konfiguration aller VMs einer Umgebung in vorgegebene neue DNS Server.

Eine tolle Aufgabe für ein kleines PowerShell-Skript (oder einen Praktikanten 🙂 ) dachte ich mir und schrieb das folgende PS Script zusammen:
(inline Kommentare sollten zur Erläuterung ausreichend sein)

Clear-Host
# AD Computer Suchkriterien definieren, damit nicht alle geändert werden, nach Bedarf anzupassen
# Get—ADComputer -FiIter {OperatingSystem —Like ‚*Server*‘ -and Name -like „VM*“‚} select —Expand DNSHostName
$ServerVMs = Get—ADComputer -Filter {OperatingSystem —Like ‚*Server*‘ -and Name -like ‚VM*‘} | select —Expand DNSHostName

# neue DNS Server in Array SDNS schreiben
# weitere DNS Server durch weitere +=  Zeilen hinzufügen falls nötig!

$DNS =@()
$DNS += „DNS-Server1-IP-Adresse“
$DNS += „DNS-Server2-IP-Adresse“

ForEach ($ServerVM in $ServerVMs)
{
Write-Host Alle NICs in $ServerVM abfragen
Get-WmiObject Win32_NetworkAdapterCOnfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $false}
$NICs = Get-WmiObject Win32_NetworkAdapterCOnfiguration -ComputerName $ServerVM | where{$_.IPEnabled -eq $true -and $_.DHCPEnabled -eq $false}

Write-Host DNS Servereinträge in allen NICs von $ServerVM ändern

ForEach ($NIC in $NICs)
{
Write-Host Bisherige DNS Server:
$NIC.DNSServerSearchOrder

# neue DNS Server in Netzwerkkarten Konfiguration eintragen
$NIC.SetDNSServerSearchorder($DNS)
}
}

Servermanager in Windows Server 2016 TP3 Core installieren

eingetragen in: 2016, Core, Powershell, Windows | 0

In der aktuellen TP3 von Windows Server 2016 gibt es (leider) die MinimalGUI Setupoption nicht mehr, sondern nur noch “Core” oder “Full GUI”, wobei letzteres alles mögliche installiert, also z.B. auch Handschrifterkennung und Mediageschichten, die für eine RemoteDesktop (Terminalserver) Installation sinnvoll sein mögen, aber nicht für die meisten anderen Server:

image

image

Bei Core gibt es den Servermanager nicht, der in der MinimalGUI Variante vorheriger Betaversionen autoamtisch installiert wurde.
ich habe die MinimalGUI Variante zu schätzen gelernt, da man damit eigentlich alles administrative machen konnte was ich bisher benötigt habe, ohne viel Ballast in der Installation zu haben.

Also habe ich mit dem aktuellen TP3 Build 10514 einfach wieder die Variante ohne GUI (Core) installiert und mit folgendem Befehl die Servermanager GUI nachinstalliert:

Install-WindowsFeature -Name RSAT -Source wim:D:\sources\install.wim:4

clip_image001

Dann z.B. mittels “shutdown –r –t 0” neustarten und nach dem Anmelden erscheint nicht nur die administrative CMD.exe, sondern auch der ServerManager:

image

Von hier ausgehend kann man dann wie bisher gewohnt (MinimalGUI) den lokalen und remote Server administrieren.

How to ReOpen the command prompt on a core server (including nested RDP session scenario)

eingetragen in: Allgemein, Core | 0

Solution for nested RDP session, as discribed below, right here:
Type <CRTL> + <ALT> + <END> on the On-Screen Keyboard inside the first RDP session, Windows Security will open in the core servers RDP session and you can open the core servers Task Manager from there.

 

the initial and only GUI interface on a Windows Server installed as core server (server without a GUI) is an administrative command prompt.

If one accidentily closed that command prompt, there is no GUI element left that you might use to reopen that command prompt. At least on first sight it looks like it…

Well if you are sitting right upfront that server it’s quite easy to bring back that command prompt, by simply pressing <CRTL> + <ALT> + <DELETE>, from there click the link to run “task manager” and from there go to “file” and “run new task”.
Now t
ype “cmd” in the “Create new task” window and you’d get your admin cmd.exe back on screen instandly! Smiley

 

Well all that is a little more complicated if you’re in an RDP session!
…ok, not really Smiley … in  a simple RDP session to a core server all you need to change in the above procedure is that you want to press <CRTL> + <ALT> + <END> to get to that Windows Security screen to run Task Manager and from there on it’s the same ballgame again.

 

Ok, but what if you’re using a cascaded RDP session aka you’re using an admin hop server aka bastion host, Bastion RDP server?

You’d have to deal with the RDP Session in an RDP session (nested RDP session) issue that doesn’t send <CRTL> + <ALT> + <DELETE> nor <CRTL> + <ALT> + <END> to the most inside RDP session (your core server) but to the admin hop or your personal workstation.

I just found one little hint on how to get the CMD up and running again quite easily.

First:
One easy way to get this done is to force a logoff of your session on the core server and relogin.
This is easily done by another user account loging into the core server and “signing off” your users session using Task manager (type “taskmgr” in command prompt).

Second:
If you don’t  have another account or another collegue to signoff your account from that server, you can use this option:

 

In the admin hop RDP session open the start menu and search for “on” which should bring up the “on-Screen Keyboard” right away as result.

 

 

pic22779

 

run the OSK

 

pic08951

 

and maximise the core servers RDP session behind it. 

now type <CRTL> + <ALT> + <END> on the OSK and Windows Security will open in the core servers RDP session and you can open the core servers Task Manager from there. 

Then again:
Use “File” and “Run new task” to start CMD.exe again.

 

pic13782

 

and there you go with a fresh administrative command prompt.

 

Powershell: Cluster-Test Automatisierung und Anlage einer Clustertest-Bericht-Historie auf SMB Share

eingetragen in: Clustering, Core, Powershell | 0

Problemstellung: automatisierte Clustertests für alle Cluster in allen Domänen durchführen und die Reports auf einem Fileserver ablegen, um diese Berichte im Falle eines Supportcase direkt zugänglich zu haben und auch eine Historie der Berichte jedes Clusters einsehen zu können.

Eine Aufgabe für PowerShell:

test-cluster

Ist in der Lage den resultierenden Bericht mittels des Attributes –ReportName im Namen anzupassen

test-cluster –cluster Cluster10 –ReportName meinReport

z.B. erzeugt eine meinReport.mht Datei des Berichtes über den Cluster10.

Gut, aber kann test-cluster auch den Pfad des Berichtes verändern?
Jap, kein Problem:

test-cluster –cluster Cluster10 –ReportName c:\Temp\Reports\meinReport

Erzeugt eine meinReport.mht Datei im Verzeichnis C:\Temp\Reports.
Ok, dieser Pfad muss dafür existieren…das Prüfen und Korrigieren wir später mittels:

if( -not (Test-Path C:\Temp\Reports) )
{
    New-Item C:\Temp\Reports -type directory
}

den Bericht an einen anderen lokalen Pfad Umleiten geht also…aber evtl. ist das ja kein Laufwerksbuchstabe, auf dem die Reports abgelegt werden sollen, sondern ein UNC/SMB Pfad…
Aber, auch das geht mit test-cluster:

test-cluster –cluster Cluster10 –ReportName \\VMM\c$\Temp\Reports\meinReport

erstellt eine meinReport.mht auf dem VMM Server unter C:\Temp\Reports… fein fein 🙂

Da ja eine Historie, also ein Archiv mit Berichten aller Cluster vorgehalten werden soll, macht es Sinn, die Dateien nicht alle meinReport.mht zu nennen, sondern mit dem Clusternamen und Datum sowie u.U. auch dem Domainnamen zu versehen. Auf letzteres könnte ich hier bei dem Kunden verzichten, da ein Ablageort/Fileserver je Domain vorgesehen wurde, habe es aber trotzdem mit eingebaut, schadet ja nicht:

Dazu ersetzen wir zuerst die –cluster und –Reportname Attribute unseres PowerShell commandlets test-Cluster durch Variablen, die wir im Folgenden dann mit “Leben” füllen:

test-cluster -cluster $cluster -ReportName $reportname

Also brauchen wir aktuell $cluster und $reportname als Eingangsvariable für unser Skript.

Um die Berichte auf dem Fileserver später zuerst nach Clusternamen und dann nach Erstellungsdatum/Zeit sortiert zu bekommen, kann man den Reportnamen wie folgt u.A. mit der Datumfunktion anpassen:

$domain = $env:USERDOMAIN
$reportpath =
\\vmm\c$\Temp\Reports\
$date = get-date -Format yyyy.MM.dd.HH.mm.ss
$reportname = $reportpath+$domain+“_“+$cluster+“_“+$date

get-date liefert ohne weitere Parameter einen Wert, der nicht für Dateipfade verwendbar ist, da er ggf. / und : enthält. Auch der –Format s Parameter den ich zuerst verwendete weil er einen “sortierbare” Ausgabe erstellt, wurde aufgrund der Doppelpunkte nicht brauchbar.

Man kann die Rückgabe von get-date aber glücklicherweise sehr individuell anpassen und bekommt mit dem von mir verwendeten –Format yyyy.MM.dd.HH.mm.ss das Format Jahr.Monat.Tag.Stunde.Minute.Sekunde jeweils als Zahl und min. zweistellig zurück, so dass nachher Berichte schon aufgrund des Dateinamens auch chronologisch sortiert werden.

Um alle Cluster einer Domain zu verarbeiten, erstelle ich zuerst eine Liste aller Cluster in die Variable $clusters:

$clusters = get-cluster -Domain $domain

Diese wird dann einfach über eine ForEach Schleife unter jeweiligem Setzen des entsprechenden $reportname abgearbeitet:

ForEach ($cluster in $clusters)
     {
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
     }

Um (optionale) Parameterübergaben für die Domäne, den Reportpfad, sowie den Cluster erweitert sieht das vollständige Skript aktuell wie folgt aus:
(wird immer wieder mal erweitert/angepasst)

#########################################################################################
#### Cluster Validation Test Script for scheduled Testing of Clusters ####

#### Author: Oliver Sommer, TrinityComputer.de GmbH

#########################################################################################

param(
[string]$domain = $env:USERDOMAIN,
[string]$reportpath,
[string]$cluster
)

# Prüfung, ob $reportpath übergeben wurde (leer ist) und falls nicht:
# Entscheidung welcher domänenspezifische $reportpath (Fileshare) zu verwenden ist
If (!$reportpath)
{
     If ($domain –eq „Dom1“)
     {
         $reportpath = „\\fileserver1\Reportspfad\“
     }

    If ($domain -eq „Dom2“)
     {
         $reportpath = „\\Fileserver2\Reportspfad\“
     }

    If ($domain -eq „Dom3“)
     {
         $reportpath = „\\Fileserver3\Reportspfad\“
     }
     If ($domain -eq „3CAN“)
     {
         $reportpath = „\\vmm\c$\Temp\Reports\“
     }
}

Clear-Host

# Prüfung ob $reportpath existiert und ggf. Erstellen des Pfades
if( -not (Test-Path $reportpath) )
{
    New-Item $reportpath -type directory
    Write-Host
    Write-Host Verzeichnis $reportpath erstellt!
    Write-Host
}

#Alle Cluster der Domäne in $clusters schreiben:
$clusters = get-cluster -Domain $domain
Write-Host In der AD DS Domäne $domain sind folgende Cluster vorhanden:
Write-Host $clusters
Write-Host

#sortierbares Datum in $date schreiben
$date = get-date -Format yyyy.MM.dd/_HH.mm.ss

# Falls ein spezifischer Cluster beim Skriptaufruf übergeben wurde:
If ($cluster)
{
     Write-Host Starte Validationtest für Cluster $cluster…
     Write-Host
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
}

# Prüfen ob $cluster als Attribut beim Skriptaufruf übergeben wurde, also ob es leer ist oder nicht:
If (!$cluster)
{
Write-Host Starte Validationtests für alle Cluster der Domäne $domain…
Write-Host
# Clusterbericht für jeden Cluster der Domain ausführen und individuellen Report ablegen:
ForEach ($cluster in $clusters)
     {
     $reportname = $reportpath+$domain+“_“+$cluster+“_“+$date
     test-cluster -cluster $cluster -ReportName $reportname
     }

}