Quantcast
Channel: Neuste Artikel
Viewing all 119 articles
Browse latest View live

SQL-Server Management Studio kostenlos herunterladen

$
0
0

Ich habe es in meinem letzten Tipp zwar schon einmal kurz erwähnt, aber ich finde, die Info ist trotzdem einen eigenen Eintrag wert. Microsoft hat sich entschieden, das SQL-Server Management Studio als eigenständiges Produkt unabhängig von den restlichen SQL-Server Features weiter zu entwickeln. Damit ist das Management Studio jetzt für jeden frei verfügbar! Das ziemlich cool, denn bisher konnte man nur die eingeschränkte Express-Edition kostenlos installieren. Das vollwertige Management-Studio konnte eigentlich nur mit dem SQL-Server installiert werden. Die RTM ist seit gestern in der Version 13.0.1601.5 offiziell released. Man kann Sie bei MSDN herunterladen

Zusätzliche Informationen zur Version und zu den Features hat man bei SQL-Sentry zusammengetragen. 

Eine Reihe von Erweiterungen für das Management-Studio findet man übrigens im SSMS Tool Pack (leider ab SSMS 2012 nicht mehr kostenlos, aber sehr preisgünstig). Alterantiv bietet sich SSMS Boost mit einer kostenlosen Community-Edition an. Sehr hilfreich und kostenlos zum automatischen Formatieren von Code ist auch der Poor Mans SQL-Formatter


Hyper-V VM per Powershell anlegen und konfigurieren

$
0
0

Das Anlegen einer virtuellen Maschine in Hyper-V geht sehr einfach. Hier zeige ich ein kleines Beispiel, dass eine Generation-2 VM anlegt, konfiguriert und ein ISO-Image zum Starten bereitstellt. 

Zuerst erzeuge ich ein Credential-Objekt, um das ISO-File für die VM aus einer Freigabe zu kopieren. Die Methode PSCredential der Klasse PSAutomation erzeugt uns dafür ein Credential-Objekt, das 2 Parameter benötigt: Den Benutzernamen und das Kennwort.

  • $password = ConvertTo-SecureString -String "Passwort" -AsPlainText -Force
  • $UserName = "Administrator"
  • $adminCred = New-Object System.Management.Automation.PSCredential ($username, $password)

 

Als nächstes wird ein Ordner für das Iso angelegt:

$isoPath = mkdir D:\iso -Force

Nun wird der Pfad für das Iso zusammengestellt und überprüft, ob der Pfad erreichbar ist. 

$SourceServer = "\\nwfs1"
$Share = "Sourcen"

Try { $Networkshare = Join-Path -Path $sourceServer -Childpath $Share -resolve -EA Stop }
Catch { Throw "Die Freigabe kann nicht gefunden werden" }

Und der ganze Spaß noch mal für den Dateinamen

$IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso'
Try { $IsoSourcePath = Join-Path -Path $NetworkShare -Childpath $IsoFileName -resolve -EA Stop }
Catch { Throw "Der Dateipfad kann nicht gefunden werden" }

Den Lokalen Pfad für das Iso-File zusammenstellen:

$IsoLocalPath = (join-path $isoPath.FullName $IsoFileName)

Mit Start-Bitstransfer wird das Iso-File kopiert. Start-Bitstransfer hat den Vorteil, dass mit dem Parameter Credential ein Benutzer übergeben werden kann, mit dem der Download ausgeführt wird. Außerdem kann der Download besser gesteuert werden. 

Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath

Nun legen wir den Zielpfad für die VM fest:

$vmPath = "d:\hyper-V\CentOS\"

Und legen Ihn an, indem wir das auch gleich das Unterverzeichnis für die VHD-Datei anlegen:

$vhdpath = mkdir -Path (Join-Path $vmPath "virtual hard disks") -Force

In unserem speziellen Fall gehen wir davon aus, dass es einen Switch mit Netzwerkzugriff gibt (Typ Extern). Um Fehler zu vermeiden, falls mehr als ein externer Switch exisitiert, wählen wir mit Select-Object genau einen Switch aus. 

$switch = Get-VMSwitch -SwitchType External | Select-Object -First 1

Als nächstes wird die virtuelle Maschine angelegt. 

$vmName =  "CentOS"
$RAM = 2GB
$vhdSize = 60GB
$vm = new-vm -Name $vmName -MemoryStartupBytes $Ram -BootDevice CD -NewVHDPath (join-path $vhdpath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize

Der VM werden 2 virtuelle Prozessoren spendiert. Das geht nicht mit New-Vm

set-vm -ProcessorCount 2 -VM $vm

Da die VM eine Linux-VM werden soll, schalten wir Secure Boot aus. 

Set-VMFirmware -EnableSecureBoot Off -VM $vm

Und als letztes verbinden wird das ISO-File mit dem virtuellen DVD-Laufwerk

Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath

In eine Funktion gegossen sieht das Ganze dann so aus:

#requires -Version 2 -Modules BitsTransfer, Hyper-V

function New-CustomVM
{
    <#
            .SYNOPSIS
            Legt eine VM an.
            .DESCRIPTION
            Legt eine VM an. Kann ein ISO-File aus dem Netzwerk kopieren und verbinden.
            Es werden eine Reihe von Default-Parametern hinterlegt. Bitte passen Sie die
            Defaults für Ihre Umgebung an.
            .EXAMPLE
            New-CustomVM
            Legt eine VM an, ohne ein ISO-File einzubinden
            .EXAMPLE
            New-CustomVM -CopyIso -UserName 'Hans' -Password 'Pwd' -SourceServer 'Server1' -Share 'Daten' -IsoFileName 'Win2012.iso' -VMName 'VMServer'
            Legt eine VM mit dem Namen VMServer an und kopiert ein ISO-File lokal in den Ordner c:\iso.
    #>

    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $false, Position = 0)]
        [Object]
        $password = (ConvertTo-SecureString -String 'Passw0rd' -AsPlainText -Force),      

        [Parameter(Mandatory = $false, Position = 1)]
        [System.String]
        $Username = 'Admin',       

        [Parameter(Mandatory = $false, Position = 2)]
        [System.String]
        $SourceServer = '\\nwfs1',       

        [Parameter(Mandatory = $false, Position = 3)]
        [System.String]
        $Share = 'Sourcen',       

        [Parameter(Mandatory = $false, Position = 4)]
        [System.String]
        $vmPath = 'd:\hyper-V\CentOS\',       

        [Parameter(Mandatory = $false, Position = 5)]
        [System.String]
        $IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso',       

        [Parameter(Mandatory = $false, Position = 6)]
        [System.String]
        $vmName = 'CentOS',      

        [Parameter(Mandatory = $false, Position = 7)]
        [System.Int64]
        $RAM = 2GB,       

        [Parameter(Mandatory = $false, Position = 8)]
        [System.Int64]
        $vhdSize = 60GB, 

        [Parameter(Mandatory = $false, Position = 9)]
        [System.String]
        $LocalIsoPath = 'C:\Iso',

        [Parameter()]
        [Switch]
        $CopyIso
    )   

    If ($CopyIso)
    {
        $adminCred = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($UserName, $password))
        Try
        {
            $Networkshare = Join-Path -Path $SourceServer -ChildPath $Share -Resolve -EA Stop
        }
        Catch
        {
            Throw 'Die Freigabe {0} kann nicht gefunden werden' -f (Join-Path -Path $SourceServer -ChildPath $Share)
        }    
        Try
        {
            $IsoSourcePath = Join-Path -Path $Networkshare -ChildPath $IsoFileName -Resolve -EA Stop
        }
        Catch
        {
            Throw 'Der Dateipfad {0} kann nicht gefunden werden' -f (Join-Path -Path $Networkshare -ChildPath $IsoFileName)
        }
        Try
        {
            $isoPath = mkdir $LocalIsoPath
        }
        Catch
        {
            Throw "Der Pfad $LocalIsoPath konnte nicht angelegt werden"
            $_.Exception
        }

        $IsoLocalPath = (Join-Path -Path $isoPath.FullName -ChildPath $IsoFileName)
        Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath
    } 

    $vhdpath = mkdir -Path (Join-Path -Path $vmPath -ChildPath 'virtual hard disks') -Force
    $switch = Get-VMSwitch -SwitchType External | Select-Object -First 1
    $vm = New-VM -Name $vmName -MemoryStartupBytes $RAM -BootDevice CD -NewVHDPath (Join-Path -Path $vhdpath -ChildPath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize
    Set-VM -ProcessorCount 2 -VM $vm
    Set-VMFirmware -EnableSecureBoot Off -VM $vm
    If ($CopyIso)
    {
        Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath
    }
}

 

 

 

 

#requires -Version 2 -Modules BitsTransfer, Hyper-V

function New-CustomVM

{

    <#

            .SYNOPSIS

            Legt eine VM an.

            .DESCRIPTION

            Legt eine VM an. Kann ein ISO-File aus dem Netzwerk kopieren und verbinden.

            Es werden eine Reihe von Default-Parametern hinterlegt. Bitte passen Sie die

            Defaults für Ihre Umgebung an.

            .EXAMPLE

            New-CustomVM

            Legt eine VM an, ohne ein ISO-File einzubinden

            .EXAMPLE

            New-CustomVM -CopyIso -UserName 'Hans' -Password 'Pwd' -SourceServer 'Server1' -Share 'Daten' -IsoFileName 'Win2012.iso' -VMName 'VMServer'

            Legt eine VM mit dem Namen VMServer an und kopiert ein ISO-File lokal in den Ordner c:\iso.

    #>

    [CmdletBinding()]

    param

    (

        [Parameter(Mandatory = $false, Position = 0)]

        [Object]

        $password = (ConvertTo-SecureString -String 'Passw0rd' -AsPlainText -Force),

       

        [Parameter(Mandatory = $false, Position = 1)]

        [System.String]

        $Username = 'Admin',

       

        [Parameter(Mandatory = $false, Position = 2)]

        [System.String]

        $SourceServer = '\\nwfs1',

       

        [Parameter(Mandatory = $false, Position = 3)]

        [System.String]

        $Share = 'Sourcen',

       

        [Parameter(Mandatory = $false, Position = 4)]

        [System.String]

        $vmPath = 'd:\hyper-V\CentOS\',

       

        [Parameter(Mandatory = $false, Position = 5)]

        [System.String]

        $IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso',

       

        [Parameter(Mandatory = $false, Position = 6)]

        [System.String]

        $vmName = 'CentOS',

       

        [Parameter(Mandatory = $false, Position = 7)]

        [System.Int64]

        $RAM = 2GB,

       

        [Parameter(Mandatory = $false, Position = 8)]

        [System.Int64]

        $vhdSize = 60GB,

 

        [Parameter(Mandatory = $false, Position = 9)]

        [System.String]

        $LocalIsoPath = 'C:\Iso',

 

        [Parameter()]

        [Switch]

        $CopyIso

 

    )

   

    If ($CopyIso)

    {

        $adminCred = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($UserName, $password))

        Try

        {

            $Networkshare = Join-Path -Path $SourceServer -ChildPath $Share -Resolve -EA Stop

        }

        Catch

        {

            Throw 'Die Freigabe {0} kann nicht gefunden werden' -f (Join-Path -Path $SourceServer -ChildPath $Share)

        }

      

        Try

        {

            $IsoSourcePath = Join-Path -Path $Networkshare -ChildPath $IsoFileName -Resolve -EA Stop

        }

        Catch

        {

            Throw 'Der Dateipfad {0} kann nicht gefunden werden' -f (Join-Path -Path $Networkshare -ChildPath $IsoFileName)

        }

   

        Try

        {

            $isoPath = mkdir $LocalIsoPath

        }

        Catch

        {

            Throw "Der Pfad $LocalIsoPath konnte nicht angelegt werden"

            $_.Exception

        }

 

        $IsoLocalPath = (Join-Path -Path $isoPath.FullName -ChildPath $IsoFileName)

        Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath

    }

 

    $vhdpath = mkdir -Path (Join-Path -Path $vmPath -ChildPath 'virtual hard disks') -Force

    $switch = Get-VMSwitch -SwitchType External | Select-Object -First 1

    $vm = New-VM -Name $vmName -MemoryStartupBytes $RAM -BootDevice CD -NewVHDPath (Join-Path -Path $vhdpath -ChildPath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize

    Set-VM -ProcessorCount 2 -VM $vm

    Set-VMFirmware -EnableSecureBoot Off -VM $vm

    If ($CopyIso)

    {

        Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath

    }

}

Programme deinstallieren mit Powershell

$
0
0

Um mit Powershell Programme zu deinstallieren, muß man mit Powershell entweder tief in die Trickkiste greifen (genau genommen in die WMI-Kiste), oder aber Powershell 5.0 installieren. Wenn Sie WMI verwenden wollen oder müssen, greifen Sie auf die Klasse Win32_Product zurück. Der Zugriff auf WMI gestaltet sich dank Powershell dabei sehr einfach: 

Get-WMIObject -Class Win32_Product -Filter "name like '%Office%'"

Die obige Zeile ruft die installierten Programme ab. Zum Deinstallieren können Sie die Methode Uninstall() verwenden. Das sieht dann so aus:

$VS = Get-WMIObject -Class Win32_Product -Filter "name = 'Microsoft Visual Studio Professional 2015'"
$VS.Uninstall()

Unglücklicherweise gibt die Klasse Win32_Product nicht alle installierten Programme zurück und ist auch nicht besonders schnell. Mit dem Powershell-Packagemanager (ab Powershell 5.0 Bestandteil von Powershell) geht es jetzt aber deutlich einfacher. 

Uninstall-Package -name '7-Zip'

Alle installierten Programme zeigt im Übrigen Get-Package:

Get-Package 

Interessant ist auch der Parameter -Providername, mit dem man nach bestimmten Installer-Typen suchen kann:

Get-Package -Providername msi

 

Weiterführende Links:

User Powershell to Find and Uninstall Software
https://blogs.technet.microsoft.com/heyscriptingguy/2011/12/14/use-powershell-to-find-and-uninstall-software/

Windows 10 - Taskmanager zeigt dauerhauft hohe Systemlast (Taskmanager durch Process Monitor ersetzen)

$
0
0

Windows 10 - bei mir hat sich diese Beziehung zu einer Haßliebe entwickelt. Ich bin wirklich inzwischen am Überlegen, ob ich nicht doch lieber einmal Linux probieren sollte. Auch nach einem Jahr habe ich nicht das Gefühl, dass Windows 10 aus der Beta-Phase raus ist, und das, obwohl ich inzwischen (aus genau diesen Gründen) nicht mehr an der Insider-Preview teilnehme. 

Beispiel gefällig? Ich habe Stunden damit zugebracht herauszufinden, warum meine CPU-Last ständig oberhalb von 50% liegt. Ich habe jetzt die Ursache gefunden - sie tut es gar nicht. Der Taskmanager zeigt einfach nur völlig falsche Werte an. Auf die Idee bin ich gekommen, nachdem ich einen Artikel gefunden habe, der beschrieb, dass es im Taskmanager den Idle-Task nicht mehr gibt, und dass daher der Task-Manager Prozess manchmal sehr hohe Lastwerte anzeigt. Daraufhin habe ich den Sysinternals Process Monitor angeworfen und - während der Taskmanager konstant fast 50% Last anzeigte, dümpelte der Procmon bei 4% Last herum. 

Procmon zeigt unter 10% Last, Taskmanager 31%
Promon vs. Taskmanager

Die beste Lösung für das Problem - Den Taskmanager gleich durch Procmon ersetzen. Dafür bring Procmon sogar eine eigene Funktionalität mit. Klicken Sie im Menü unter Options einfach auf "Replace Task Manager", und Procmon erledigt den Rest für Sie. Wählen Sie die Option erneut, stellt Procmon den Taskmanager wieder her. Und da es sich auch bei Procmon um ein Microsoft-Tool handelt, muß man sich auch keine weiteren Gedanken machen. Das besser Werkzeug ist der Procmon eh. 

 

Weiterführende Links:

Systinternal Process Monitor
https://technet.microsoft.com/de-de/sysinternals/processmonitor.aspx

Unix/MySQL Timestamp in Datumswerte mit Powershell umwandeln

$
0
0

In Unix und MySQL werden Datumswerte oft als Timestamps angegeben. Ein Timestamp ist eigentlich ein Datums/Zeitwerte, der aber als Integer gespeichert ist und die Sekunden ab dem 1.01.1970 angibt. Diese Zeitzählung wird auch als "Epoch date" bezeichnet.

Die Umwandlung in einen Datumswert in Powershell ist eigentlich recht einfach, da uns Powershell alle zur Umrechung notwendigen Funktionen zur Verfügung stellt. Das Datum des 1.1.1970 liefert uns get-Date:

Get-Date '1/1/1970'

Get-Date liefert ein Objekt vom Type Datetime zurück. Alle Objekte vom Typ Datetime besitzen eine Reihe von Methoden für die Datumsmanipulation. Wir benötigen hier die Methode AddSeconds() zum Aufaddieren von Sekunden:

$Timestamp = 1464257993
(Get-Date '1/1/1970').AddSeconds($Timestamp)

Die Rückkonvertierung können wir mti Hilfe von New-Timespan durchführen. Dieses Cmdlet berechnet eine Zeitspanne anhand von zwei Daten und gibt unter anderem auch die Anzahl in Sekunden zwischen den beiden Zeitspannen aus:

[int]$timeStamp = (New-Timespan -Start (get-Date '1/1/1970') -End (get-date)).TotalSeconds

Das Ganze können wir auch in zwei kleine Funktionen gießen:

<#
  .Synopsis
  Konvertiert einen Timestamp (Epochdate) in Datetime
  .DESCRIPTION
  Konvertiert einen Timestamp (Epochdate) in Datetime. Als Übergabeparameter wird der Timestamp als
  Integer übergeben
  .EXAMPLE
  ConvertFrom-UnixTimeStamp -TimeStamp 1464257993
#>
Function ConvertFrom-UnixTimeStamp
{
param (
  # Der Zeitstempel als Integer
  [Parameter(ValueFromPipeline=$true)]
  [int]$TimeStamp
)

  (Get-Date '1/1/1970').AddSeconds($Timestamp)
}

Und eine Funktion zum Umwandeln in Timestamps:

<#
  .Synopsis
  Konvertiert einen Datetime-Datentyp in eine Unix Timestamp (Epochdate)
  .DESCRIPTION
  Konvertiert einen Datetime-Datentyp in eine Unix Timestamp (Epochdate). Als Übergabeparameter wird ein Datum
  (auch als String) angenommen
  .EXAMPLE
  Convertto-UnixTimestamp -Date '11.11.2011'
#>
Function ConvertTo-UnixTimeStamp
{
param (
  # Der umzuwandelnde Datumstyp
  [Parameter(ValueFromPipeline=$true)]
  [ValidateScript({ Try{ $_ -as [datetime]} Catch { $false } })]
  $Date = (get-Date)
)

  [int](New-Timespan -Start (get-Date '1/1/1970') -End (get-date $date)).TotalSeconds
}

Eine umfangreiche Beschreibung für die Konvertierung in verschiedenste Formate findet man hier:
http://www.epochconverter.com/

Datenbanken migrieren von mySQL zu SQL-Server

$
0
0

SQL-Server und mySql sind leider SQL-seitig nicht wirklich kompatibel. So gibt es zwar die Möglichkeit, eine Datenbank in mySQL als Script zu exportieren, aber leider kann man das Script auf dem SQL-Server nicht mehr für den Import benutzen. Der beste Weg für den Import führt daher über den SQL Server Migration Wizard. Der Migration Wizard steht für verschiedene Datenbanken zur Verfügung und hilft z.B. auch bei der Migration von Access-Datenbanken zu SQL-Server. Da das Tool recht komplex ist, möchte ich hier nur kurz zeigen, wie man eine einfach Migration durchführt, ohne auf die schmutzigen kleinen Details des Tools eingehen zu wollen. Ich verwende hierzu die derzeit aktuelle Version 6.0.1, 6.1 (für SQL-Server 2016) ist derzeit in der Beta-Phase.

Sie benötigen auf dem Rechner, auf dem Sie den SSMA einrichten wollen, zuerst einmal einen mySQL-ODBC-Treiber. Haben Sie die mySQL-Datenbank unter Windows auf dem gleichen Rechner installiert, dann müssen Sie nichts weiter machen, denn mySQL installiert den passenden ODBC-Treiber gleich mit. Ansonsten laden Sie den Treiber einfach bei mysql.com herunter. Nutzen Sie den 64-Bit Treiber, der SSMA wird nämlich auch in einer 64-Bit-Version installiert. Eine Konto für die Authentifizierung ist übrigens nicht notwendig, klicken Sie einfach auf den Link "No thanks, just start my download", wenn Sie nach Ihrem Login gefragt werden. Anschliessend installieren Sie den SSMA.

Wenn Sie den Migration Assistenten zum ersten Mal starten, müssen Sie ein Migrationsprojekt erstellen. Wählen Sie hierfür im Menü File "New Project" aus. Wichtig ist, dass Sie im folgenden Fenster das Migrationsziel auswählen. Standardmässig ist hier Azure angegeben. Leider können Sie das Ziel im Projekt selber dann nicht mehr ändern. Das kann ziemlich verwirrend sein!

Projekt anlegen   2

Nun müssen Sie eine Verbindung zum Quell- und zum Zielsystem herstellen. Wählen Sie hierfür in der Toolbar zuerst "Connect to MySql". Wählen Sie im Verbindungsfenster den Provider aus - dies ist der ODBC-Treiber, den Sie installiert haben. Ist hier kein Treiber sichtbar, obwohl Sie einen Treiber installiert haben, dann prüfen Sie, ob Sie den Treiber und SSMA beide in der gleichen Version (32-Bit / 64-Bit) installiert bzw. gestartet haben. Außerdem benötigen Sie den Namen des Quellservers, den mySQL-Port (standardmässig 3306), sowie ein Konto mit Leserechten auf dem mySQL-System. 

Nun verbinden Sie sich mit dem SQL-Server. 

 

Im nächsten Schritt müssen Sie das Schema synchronisieren. Wählen Sie hierfür im mySQL Metadata Explorer die Datenbank(en) aus, die Sie migrieren möchten. Wenn Sie nur einzelne Tabellen oder Sichten migrieren möchten, können Sie die benötigten Objekte im Metadata-Explorere an- oder abwählen. Wenn die Zieldatenbank auf dem SQL-Server anders heißen soll als in MySQL, klicken Sie außerdem auf den Button Modify und geben Sie den Namen der Datenbank an. Anschliessend wählen Sie "Convert Schema" (1) in der Toolbar. Wenn alles glatt läuft, sehen Sie im Output-Fenster unten die Zieldatenbank. Der SSMA hat die Daten jetzt analysiert, allerdings noch keine Migration durchgeführt. 

Öffnen Sie im nächsten Schritt im SQL Server Metadata Explorer das Kontextmenü der zu migrierende Datenbank und wählen Sie "Synchronize with Database". Nun wird das Schema (die Datenbankobjekte, jedoch noch ohne Daten) im SQL-Server angelegt.

Jetzt müssen nur noch die Daten über den Button "Migrate Data" von mySQL zu SQL-Server konvertiert werden, und schon sind die Daten im SQL-Server.

Es gibt noch eine ganze Reihe von Optionen, die im SSMA gesetzt werden können, wie z.B. das Mapping der Datentypen (Reiter Type-Mapping). Eine Referenz zur Typkompatiblität finden Sie bei mysql unter Microsoft SQL Server Type Mapping. Für die Konvertierung von Timestamps habe ich den Artikel Unix/MySQL Timestamp in Datumswerte mit Powershell umwandeln geschrieben. Hier finden Sie auch eine Referenz zu Konvertierungsmöglichkeiten in anderen Script- und Programmiersprachen. 

Links:

How to Migrate a MySQL Database to SQL Server
http://www.alaskasql.org/Blog/Post/24/How-to-Migrate-a-MySQL-Database-to-SQL-Server

MySQL to SQL Server Migration: How to Use SSMA
https://blogs.msdn.microsoft.com/ssma/2011/02/07/mysql-to-sql-server-migration-how-to-use-ssma/

Die Startzeit / Reboot des Servers herausfinden

$
0
0

Jefrey Snover hat gerade ein Modul in der Powershell Gallery gepostet, das die letzte Reboot-Zeit aus dem Eventlog ausliest: https://www.powershellgallery.com/packages/get-lastreboot/0.1.1/DisplayScript. Dabei fiel mir ein, dass es doch auch noch dieses tolle Tool Systeminfo gibt, dass an der Kommandozeile alle möglichen Systeminformationen ausgibt - auch die Systemstartzeit. Das großartige an diesem Tool ist aber, dass es die Ausgabe auch ins csv-Format umwandeln kann, indem man den Parameter -FO aufruft. Die gesamten Informationen werden dann ins csv-Format umgewandelt, mit dem Powershell wiederum ganz hervorragend umgehen kann. Und so kann man dann ganz hervorragend die Daten von systeminfo direkt in Powershell weiterverarbeiten: 

systeminfo /FO csv | convertfrom-csv

Das Ergebnis sieht so aus: 

Hostname : ACER1
Betriebssystemname : Microsoft Windows 10 Pro
Betriebssystemversion : 10.0.10586 Nicht zutreffend Build 10586
Betriebssystemhersteller : Microsoft Corporation
Betriebssystemkonfiguration : Eigenst?ndige Arbeitsstation
Betriebssystem-Buildtyp : Multiprocessor Free
Registrierter Benutzer :
Registrierte Organisation :
Produkt-ID : 00330-80000-00000-AA738
Urspr?ngliches Installationsdatum : 25.02.2016, 16:47:17
Systemstartzeit : 19.05.2016, 09:17:11
Systemhersteller : Acer
Systemmodell : Aspire V3-771
[...]

Und natürlich können wir jetzt auch das machen: 

systeminfo /FO csv | convertfrom-csv | Select-Object Systemstartzeit

Einziges Manko: Systeminfo ist lokalisiert, der obige Befehl wäre auf einem englischen System also ohne Anpassung nicht lauffähig. :-(

 

 

Office 365, Azure AD, ADSync und ADFS - eine Einführung und Begriffsklärung

$
0
0

Mit diesem Artikel beginne ich eine kleine Serie zum Thema Office 365 Benutzerverwaltung. Im ersten Teil möchte ich erst einmal klären, wie Office 365 und Azure AD zusammen hängen und wofür man den Azure AD Sync Dienst und Active Directory Federation Services (ADFS) benötigt. 

Wofür brauche ich Azure AD, wenn ich doch Office 365 einsetze?

Azure AD (Actice Directory) ist ein Benutzerverzeichnis, das von Microsoft ohne Installation eines eigenen Servers auf den Microsoft-Servern bereitgestellt wird. Office 365 verwendet Azure AD zur Speicherung Ihrer Office 365 Benutzerkonten. Dafür wird beim Anlegen eines Office 365-Accounts automatisch ein Azure-AD Verzeichnis angelegt.
Azure AD speicher Ihre Benutzerinformationen. Immer, wenn Sie im Office 365 einen neuen Benutzeraccount anlegen oder Benutzerinformationen ändern, werden tatsächlich Änderungen im Azure AD durchgeführt.

Benutzer mit einem lokalen AD zusammenführen

Um zu verhindern, dass Ihre Benutzer sich mehrere Kennwörter merken müssen – eins für Ihr Outlook und Sharepoint, und eins für Ihre lokale Anmeldung am PC – hat Microsoft die Möglichkeit zur Verfügung gestellt, Ihre Benutzerkonten ins Azure AD zu synchronisieren. Dafür benötigen Sie ein Tool namens Azure AD Sync (ehemals Dirsync), das Sie auf einem Server in Ihrem Netzwerk installieren („On Premise“). AAD Sync prüft in regelmäßigen Abständen Ihre Verzeichnisse (lokales AD oder, wenn eine Rücksynchronisation gewünscht wird, auch Ihr Azure AD) und synchronisiert Daten wie Kennwörter zwischen den Verzeichnissen. Die synchronisierten Verzeichnisse bleiben nach wir vor getrennt, aber die Daten können auf dem gleichen Stand gehalten werden. Die Synchronisation kann jederzeit abgebrochen werden.
Durch AAD Sync brauchen Ihre Benutzer sich nur noch ein Kennwort zu merken, da die Kennwörter im lokalen AD und im Internet immer gleich sind. Was Azure AD jedoch nicht leisten kann ist ein Single Sign on, wie er normalerweise auf einem Domänen-PC ausgeführt wird. Das bedeutet, daß z.B. der Zugriff auf Ihren Office 365 Sharepoint eine zusätzliche Anmeldung auf der Sharepoint Website erfordert, auch wenn das Kennwort lokal wie auf dem Sharepoint dank Azure AD das gleich ist. Um einen Single Sign on zu ermöglichen, benötigen Sie ADFS (Active Diretory Federation Services).

Single Sign on mit Office 365

Damit Ihre Benutzer nicht für jede Office 365 Ressource eine Anmeldung durchführen müssen, sondern wie in einem lokalen Netzwerk üblich nur eine Anmeldung am PC durchführen und dann Zugriff auf alle Ressourcen haben, benötigen Sie Active Directory Federation Services (ADFS).
ADFS ist ein Dienst, der dazu dienst, die Anmeldungen von Websites „befreundeter“ Unternehmen in Ihr AD umzuleiten. Ein Beispiel für ähnliche Dienste, die Sie vermutlich zumindest schon oft gesehen haben, sind die Anmeldungen auf Websites via Google oder Facebook.

Google Logon

Anstatt auf einer Website ein neues Benutzerkonto anzulegen, verwenden Sie einfach Ihren Google-Account. Das Prinzip dahinter funktioniert so, dass die Website, an der Sie sich anmelden, Ihren Client im Hintergrund an den Anmeldeserver von Google weiterleitet. Ihre Google-Anmeldeinformationen werden von Google überprüft, und wenn Sie sich korrekt angemeldet haben, wird Ihrem Client ein Anmeldetoken ausgestellt und digital signiert (vor Änderungen geschützt und mit einem Stempel versehen, der sicher stellt, dass das Anmeldetoken wirklich von Google erzeugt wurde). Dieses Anmeldetoken gibt Ihre Clientsoftware an die Website zurück. Da die Website google vertraut, kann Sie nun die Anmeldeinformationen von Google verwenden, um für Sie ein Konto zu erstellen, dass mit dem Google-Konto verknüpft ist.


Anfordern und einrichten eines (kostenlosen) SSL-Zertifikats unter Windows

$
0
0

In meiner kleinen Reihe über Einrichtung und Verwaltung von Azure wird es auch um die Einrichtung von ADFS-Servern für Office 365 gehen. Für ADFS benötigen Sie, auch für Testzwecke, ein gültiges SSL-Zertifikat. In diesem Artikel zeige ich, wie Sie dafür einen Zertifikatsrequest erstellen und wie Sie bei Comodo ein 90 Tage gültiges SSL-Zertifikat beantragen können. Das Testzertifikat ist ein ganz normales SSL-Zertifikat, das bei Comodo auch verlängert werden kann. Die einzige Einschränkung ist die Laufzeit von 90 Tagen. Für die Verwendung als Zertifikat für Webserver würde ich LetsEncrypt empfehlen, da man hier komplett kostenlose SSL-Zertifikate bekommt. 

SSL-Zertifikats-Request erstellen

Um ein Zertifikat bei einer Zertifizierungsstelle zu beantragen, benötigen Sie eine Zertifikats-Anforderung. Die kann Ihnen z.B. von der IIS-Konsole erstellt werden. Einfacher geht es aber mit einem freien Tool von Digicert, die selber auch Zertifikatsanbieter sind. Laden Sie dazu einfach das Digicert Certificate Utility for Windows https://www.digicert.com/util/ auf den Rechner, auf dem das Zertifikat erstellt werden soll, herunter. Wichtig ist, dass Sie das Tool wirklich auf dem Rechner starten, auf dem das Zertifikat installiert werden soll, da mit dem Zeritifikatsrequest ein privater Schlüssel erstellt wird, der den Rechner nicht verlässt und der zusammen mit dem Zertifikat benötigt wird. Den Schlüssel später auf den Zielrechner zu exportieren ist zwar möglich, aber sehr umständlich. Das Certificate Utility muss auch nicht installiert werden, insofern sollte der Aufruf auch auf einem Server unproblematisch sein.

Das Tool kommt in einem Zip-File. Entpacken Sie es und starten Sie DigicertUtil.exe. Nachdem Sie dem Lizenzvertrag zugestimmt haben, öffnet sich die Digicert-Konsole. Hier Wählen Sie gleich im ersten Fenster oben rechts den Eintrag „Create CSR“.

CreateCSR 1

Geben Sie jetzt die Zertifikatsinformationen ein. Das Utility gibt dabei auch Hilfestellung – auf der rechten Seite finden Sie Informationen zu den Daten, die gewünscht sind. 

CreateCSR 2

 

Die meisten Daten hier sind selbsterklärend. Als Zertifikatstyp wählen Sie in unserem Fall SSL. Code Signing Zertifikate benötigen Sie für die Signatur von Programmen oder Powershell-Scripten. Als Common Name (CN) wählen Sie den DNS-Namen, unter dem der Server angefragt wird (in meinem Fall ADFS.Tonitester.work). Wenn Ihr Server unter mehreren Namen erreichbar sein soll, können Sie im Feld „Subject Alterative Names“ weitere Namen eingeben. Im Feld Key Size übernehmen sie am besten die Standardvorgabe von 2048 Bit. Anschließend klicken Sie auf „Generate“. Das Zertifikats-Utility generierte Ihnen dann einen Textschlüssel, der den Request darstellt und den Sie bei der Zertifikats-Registrierungsstelle einreichen müssen. Den Request können Sie in einer Textdatei speichern oder gleich ins Clipboard kopieren.

SSL-Zertifikat beantragen

Gehen Sie jetzt zu www.comodo.com. Comodo ist ein Anbieter für offiziell anerkannte Zertifikate. Wählen Sie auf der Startseite „SSL Cetificates“ und dann „Free SSL Certificates“.

GetSSL 3

Auf der folgenden Seite starten Sie "Free SSL Trial".

GetSSL 4

Nun benötigen Sie den Zertifikats-Request, den Certutil Ihnen erzeugt hat. Kopieren Sie ihn in das entsprechende Feld unter „Provide your CSR“.

GetSSL 5

Um zu validieren, dass Sie wirklich der Besitzer der Domäne sind, liest Comodo den Admin-C aus Ihrem DNS-Eintrag. Es werden auch alternative Adressen angegeben. Die Adresse wird verwendet, um eine Validierungsmail zu schicken. 

GetSSL 6

Legen Sie außerdem ein Benutzerkonto bei Comodo an. 

GetSSL 7

Es wird ein Validierungscode an die ausgewählte email-Adresse verschickt. Dieser muß unter Domain Control Validation eingegeben werden. 

GetSSL 8

Das Zertifikat kommt innerhalb weniger Minuten als ZIP-Datei per email. Kopieren Sie die ZIP-Datei auf den ADFS-Server, entpacken Sie sie und installieren Sie die crl-Datei, die dem Namen Ihrer Domäne entspricht. Die anderen mitgelieferten Zertifikate sind die Zertifikate der Stammzertifizierungsstelle und die Zertifikatskette. Sie werden nicht benötigt.

Zur Installation öffnen Sie einfach das Kontextmenü des Zertifikats und wählen „Install Certificate“.

GetSSL 9

Wählen Sie den Zertifikatsspeicher des Computers aus. 

GetSSL 10

Damit ist Ihr Zertifikat installiert. Überprüfen können Sie das z.B., indem Sie die Powershell öffnen und folgenden Befehl eingeben: 

dir Cert:\LocalMachine\My | Select Thumbprint,Subject,NotBefore,NotAfter

Es werden Ihnen alle lokal installierten Zertifikate angezeigt. Thumbprint ist eine Checksumme, die das Zertifikat eindeutig indentifiziert, Subject ist der Name, den Sie im Request eingegeben haben, und NotAfter sollte bei unserem Testzertifikat 90 Tage in der Zukunft liegen. Nun können Sie das Zertifikat z.B. zur Absicherung Ihres Webservers, SQL-Server oder allen Diensten verwenden, die auf Public-Key-Verschlüsselung setzen. 

SQL Server 2016 Developer Edition (Funktionsidentisch mit Enterprise) jetzt kostenlos!

$
0
0

Immer wenn mein Frust auf Microsoft so richtig groß ist, machen Sie wieder was richtig cooles. Windows 10 nervt mich manchmal mächtig ab. Aber dafür hat Microsoft jetzt die gestern offiziell releaste Version 2016 in der Developer-Edition kostenlos verfügbar gemacht! Die Developer-Edition darf nur für Test-und Programmierzwecke eingesetzt werden, ist aber ansonsten voll Featureidentisch mit der Enterprise-Edition! Man kann Sie direkt bei MSDN herunterladen. Außerdem sollten Sie beachten, dass das SQL-Server Management Studio jetzt nicht mehr Bestandteil der SQL-Server Installation ist, weil es als eigenes Produkt weiterentewickelt wird. Den Link zum Download finden Sie ebenfalls beim MSDN. 

Eine Sache gibt es zu beachten: Die Developer-Edition hat den Netzwerkzugriff im Gegensatz zu den anderen Editions standardmässig deaktiviert. Er kann aber problemlos aktiviert werden. Starten Sie dafür nach der Installation den SQL-Server Configuration Manager und wählen Sie hier unter SQL-Server Network Configuration "Protocols for MSSQL-Server". Hier sehen sie die aktiven Zugriffsprotokolle. TCP/IP ist allerding deaktviert.

enable tcpip 1

Doppelklicken Sie zum Aktivieren auf "TCP/IP". Im folgenden Fenster stellen Sie "Enabled" auf Yes.

enable tcpip 2

Zum Aktivieren des Netzwerkzugriffs ist allerdings ein Neustart des Dienstes notwendig. Der Server läuft bei einer Standardinstanz dann auf Port 1433, bei einer benannten Instanz wird ein dynamischer (automatisch zugewiesener) Port verwendet. Diese Einstellungen können Sie ebenfalls im Configuration Manager ändern, indem Sie den Reiter "IP Addresses" wählen. 

set port 3

Hier können Sie den Port eintragen, auf dem der SQL-Server Anfragen annehmen soll. Ist hier kein Port eingetragen, aber dafür eine Null bei dynamic Ports gesetzt, wählt der SQL-Dienst bei jedem Start automatisch einen Port. Entfernen Sie die 0 und tragen Sie stattdessen einen festen Port ein, wird dieses Verhalten deaktiviert. Auch für das Ändern des Ports ist ein Neustart notwendig. 

SQL-Server Management Studio kostenlos herunterladen

$
0
0

Ich habe es in meinem letzten Tipp zwar schon einmal kurz erwähnt, aber ich finde, die Info ist trotzdem einen eigenen Eintrag wert. Microsoft hat sich entschieden, das SQL-Server Management Studio als eigenständiges Produkt unabhängig von den restlichen SQL-Server Features weiter zu entwickeln. Damit ist das Management Studio jetzt für jeden frei verfügbar! Das ziemlich cool, denn bisher konnte man nur die eingeschränkte Express-Edition kostenlos installieren. Das vollwertige Management-Studio konnte eigentlich nur mit dem SQL-Server installiert werden. Die RTM ist seit gestern in der Version 13.0.1601.5 offiziell released. Man kann Sie bei MSDN herunterladen

Zusätzliche Informationen zur Version und zu den Features hat man bei SQL-Sentry zusammengetragen. 

Eine Reihe von Erweiterungen für das Management-Studio findet man übrigens im SSMS Tool Pack (leider ab SSMS 2012 nicht mehr kostenlos, aber sehr preisgünstig). Alterantiv bietet sich SSMS Boost mit einer kostenlosen Community-Edition an. Sehr hilfreich und kostenlos zum automatischen Formatieren von Code ist auch der Poor Mans SQL-Formatter

Hyper-V VM per Powershell anlegen und konfigurieren

$
0
0

Das Anlegen einer virtuellen Maschine in Hyper-V geht sehr einfach. Hier zeige ich ein kleines Beispiel, dass eine Generation-2 VM anlegt, konfiguriert und ein ISO-Image zum Starten bereitstellt. 

Zuerst erzeuge ich ein Credential-Objekt, um das ISO-File für die VM aus einer Freigabe zu kopieren. Die Methode PSCredential der Klasse PSAutomation erzeugt uns dafür ein Credential-Objekt, das 2 Parameter benötigt: Den Benutzernamen und das Kennwort.

  • $password = ConvertTo-SecureString -String "Passwort" -AsPlainText -Force
  • $UserName = "Administrator"
  • $adminCred = New-Object System.Management.Automation.PSCredential ($username, $password)

 

Als nächstes wird ein Ordner für das Iso angelegt:

$isoPath = mkdir D:\iso -Force

Nun wird der Pfad für das Iso zusammengestellt und überprüft, ob der Pfad erreichbar ist. 

$SourceServer = "\\nwfs1"
$Share = "Sourcen"

Try { $Networkshare = Join-Path -Path $sourceServer -Childpath $Share -resolve -EA Stop }
Catch { Throw "Die Freigabe kann nicht gefunden werden" }

Und der ganze Spaß noch mal für den Dateinamen

$IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso'
Try { $IsoSourcePath = Join-Path -Path $NetworkShare -Childpath $IsoFileName -resolve -EA Stop }
Catch { Throw "Der Dateipfad kann nicht gefunden werden" }

Den Lokalen Pfad für das Iso-File zusammenstellen:

$IsoLocalPath = (join-path $isoPath.FullName $IsoFileName)

Mit Start-Bitstransfer wird das Iso-File kopiert. Start-Bitstransfer hat den Vorteil, dass mit dem Parameter Credential ein Benutzer übergeben werden kann, mit dem der Download ausgeführt wird. Außerdem kann der Download besser gesteuert werden. 

Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath

Nun legen wir den Zielpfad für die VM fest:

$vmPath = "d:\hyper-V\CentOS\"

Und legen Ihn an, indem wir das auch gleich das Unterverzeichnis für die VHD-Datei anlegen:

$vhdpath = mkdir -Path (Join-Path $vmPath "virtual hard disks") -Force

In unserem speziellen Fall gehen wir davon aus, dass es einen Switch mit Netzwerkzugriff gibt (Typ Extern). Um Fehler zu vermeiden, falls mehr als ein externer Switch exisitiert, wählen wir mit Select-Object genau einen Switch aus. 

$switch = Get-VMSwitch -SwitchType External | Select-Object -First 1

Als nächstes wird die virtuelle Maschine angelegt. 

$vmName =  "CentOS"
$RAM = 2GB
$vhdSize = 60GB
$vm = new-vm -Name $vmName -MemoryStartupBytes $Ram -BootDevice CD -NewVHDPath (join-path $vhdpath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize

Der VM werden 2 virtuelle Prozessoren spendiert. Das geht nicht mit New-Vm

set-vm -ProcessorCount 2 -VM $vm

Da die VM eine Linux-VM werden soll, schalten wir Secure Boot aus. 

Set-VMFirmware -EnableSecureBoot Off -VM $vm

Und als letztes verbinden wird das ISO-File mit dem virtuellen DVD-Laufwerk

Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath

In eine Funktion gegossen sieht das Ganze dann so aus:

#requires -Version 2 -Modules BitsTransfer, Hyper-V

function New-CustomVM
{
    <#
            .SYNOPSIS
            Legt eine VM an.
            .DESCRIPTION
            Legt eine VM an. Kann ein ISO-File aus dem Netzwerk kopieren und verbinden.
            Es werden eine Reihe von Default-Parametern hinterlegt. Bitte passen Sie die
            Defaults für Ihre Umgebung an.
            .EXAMPLE
            New-CustomVM
            Legt eine VM an, ohne ein ISO-File einzubinden
            .EXAMPLE
            New-CustomVM -CopyIso -UserName 'Hans' -Password 'Pwd' -SourceServer 'Server1' -Share 'Daten' -IsoFileName 'Win2012.iso' -VMName 'VMServer'
            Legt eine VM mit dem Namen VMServer an und kopiert ein ISO-File lokal in den Ordner c:\iso.
    #>

    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $false, Position = 0)]
        [Object]
        $password = (ConvertTo-SecureString -String 'Passw0rd' -AsPlainText -Force),      

        [Parameter(Mandatory = $false, Position = 1)]
        [System.String]
        $Username = 'Admin',       

        [Parameter(Mandatory = $false, Position = 2)]
        [System.String]
        $SourceServer = '\\nwfs1',       

        [Parameter(Mandatory = $false, Position = 3)]
        [System.String]
        $Share = 'Sourcen',       

        [Parameter(Mandatory = $false, Position = 4)]
        [System.String]
        $vmPath = 'd:\hyper-V\CentOS\',       

        [Parameter(Mandatory = $false, Position = 5)]
        [System.String]
        $IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso',       

        [Parameter(Mandatory = $false, Position = 6)]
        [System.String]
        $vmName = 'CentOS',      

        [Parameter(Mandatory = $false, Position = 7)]
        [System.Int64]
        $RAM = 2GB,       

        [Parameter(Mandatory = $false, Position = 8)]
        [System.Int64]
        $vhdSize = 60GB, 

        [Parameter(Mandatory = $false, Position = 9)]
        [System.String]
        $LocalIsoPath = 'C:\Iso',

        [Parameter()]
        [Switch]
        $CopyIso
    )   

    If ($CopyIso)
    {
        $adminCred = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($UserName, $password))
        Try
        {
            $Networkshare = Join-Path -Path $SourceServer -ChildPath $Share -Resolve -EA Stop
        }
        Catch
        {
            Throw 'Die Freigabe {0} kann nicht gefunden werden' -f (Join-Path -Path $SourceServer -ChildPath $Share)
        }    
        Try
        {
            $IsoSourcePath = Join-Path -Path $Networkshare -ChildPath $IsoFileName -Resolve -EA Stop
        }
        Catch
        {
            Throw 'Der Dateipfad {0} kann nicht gefunden werden' -f (Join-Path -Path $Networkshare -ChildPath $IsoFileName)
        }
        Try
        {
            $isoPath = mkdir $LocalIsoPath
        }
        Catch
        {
            Throw "Der Pfad $LocalIsoPath konnte nicht angelegt werden"
            $_.Exception
        }

        $IsoLocalPath = (Join-Path -Path $isoPath.FullName -ChildPath $IsoFileName)
        Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath
    } 

    $vhdpath = mkdir -Path (Join-Path -Path $vmPath -ChildPath 'virtual hard disks') -Force
    $switch = Get-VMSwitch -SwitchType External | Select-Object -First 1
    $vm = New-VM -Name $vmName -MemoryStartupBytes $RAM -BootDevice CD -NewVHDPath (Join-Path -Path $vhdpath -ChildPath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize
    Set-VM -ProcessorCount 2 -VM $vm
    Set-VMFirmware -EnableSecureBoot Off -VM $vm
    If ($CopyIso)
    {
        Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath
    }
}

 

 

 

 

#requires -Version 2 -Modules BitsTransfer, Hyper-V

function New-CustomVM

{

    <#

            .SYNOPSIS

            Legt eine VM an.

            .DESCRIPTION

            Legt eine VM an. Kann ein ISO-File aus dem Netzwerk kopieren und verbinden.

            Es werden eine Reihe von Default-Parametern hinterlegt. Bitte passen Sie die

            Defaults für Ihre Umgebung an.

            .EXAMPLE

            New-CustomVM

            Legt eine VM an, ohne ein ISO-File einzubinden

            .EXAMPLE

            New-CustomVM -CopyIso -UserName 'Hans' -Password 'Pwd' -SourceServer 'Server1' -Share 'Daten' -IsoFileName 'Win2012.iso' -VMName 'VMServer'

            Legt eine VM mit dem Namen VMServer an und kopiert ein ISO-File lokal in den Ordner c:\iso.

    #>

    [CmdletBinding()]

    param

    (

        [Parameter(Mandatory = $false, Position = 0)]

        [Object]

        $password = (ConvertTo-SecureString -String 'Passw0rd' -AsPlainText -Force),

       

        [Parameter(Mandatory = $false, Position = 1)]

        [System.String]

        $Username = 'Admin',

       

        [Parameter(Mandatory = $false, Position = 2)]

        [System.String]

        $SourceServer = '\\nwfs1',

       

        [Parameter(Mandatory = $false, Position = 3)]

        [System.String]

        $Share = 'Sourcen',

       

        [Parameter(Mandatory = $false, Position = 4)]

        [System.String]

        $vmPath = 'd:\hyper-V\CentOS\',

       

        [Parameter(Mandatory = $false, Position = 5)]

        [System.String]

        $IsoFileName = 'CentOS-6.8-x86_64-bin-DVD1.iso',

       

        [Parameter(Mandatory = $false, Position = 6)]

        [System.String]

        $vmName = 'CentOS',

       

        [Parameter(Mandatory = $false, Position = 7)]

        [System.Int64]

        $RAM = 2GB,

       

        [Parameter(Mandatory = $false, Position = 8)]

        [System.Int64]

        $vhdSize = 60GB,

 

        [Parameter(Mandatory = $false, Position = 9)]

        [System.String]

        $LocalIsoPath = 'C:\Iso',

 

        [Parameter()]

        [Switch]

        $CopyIso

 

    )

   

    If ($CopyIso)

    {

        $adminCred = (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($UserName, $password))

        Try

        {

            $Networkshare = Join-Path -Path $SourceServer -ChildPath $Share -Resolve -EA Stop

        }

        Catch

        {

            Throw 'Die Freigabe {0} kann nicht gefunden werden' -f (Join-Path -Path $SourceServer -ChildPath $Share)

        }

      

        Try

        {

            $IsoSourcePath = Join-Path -Path $Networkshare -ChildPath $IsoFileName -Resolve -EA Stop

        }

        Catch

        {

            Throw 'Der Dateipfad {0} kann nicht gefunden werden' -f (Join-Path -Path $Networkshare -ChildPath $IsoFileName)

        }

   

        Try

        {

            $isoPath = mkdir $LocalIsoPath

        }

        Catch

        {

            Throw "Der Pfad $LocalIsoPath konnte nicht angelegt werden"

            $_.Exception

        }

 

        $IsoLocalPath = (Join-Path -Path $isoPath.FullName -ChildPath $IsoFileName)

        Start-BitsTransfer -Credential $adminCred -Source $IsoSourcePath -Destination $IsoLocalPath

    }

 

    $vhdpath = mkdir -Path (Join-Path -Path $vmPath -ChildPath 'virtual hard disks') -Force

    $switch = Get-VMSwitch -SwitchType External | Select-Object -First 1

    $vm = New-VM -Name $vmName -MemoryStartupBytes $RAM -BootDevice CD -NewVHDPath (Join-Path -Path $vhdpath -ChildPath system.vhdx) -SwitchName $switch.Name -Generation 2 -NewVHDSizeBytes $vhdSize

    Set-VM -ProcessorCount 2 -VM $vm

    Set-VMFirmware -EnableSecureBoot Off -VM $vm

    If ($CopyIso)

    {

        Set-VMDvdDrive -VMName $vm.VMName -Path $IsoLocalPath

    }

}

Root-Zertifikat aus dem Zertifikats-Store entfernen

$
0
0

Haben Sie schon einmal versucht, ein per Gruppenrichtlinien verteiltes Root-Zertifikat wieder zu entfernen? Wie sich herausstellt, ist das über das Zertifikats-Plug-In in der Management-Konsole gar nicht so einfach. Hilfe verschafft hier das Kommandozeilentools Certutil in Verbindung mit Powershell.

Certutil besitzt einen Parameter -delstore, mit dem man Zertifikate aus dem Store entfernen kann. Ruft man Certutil -delstore -? auf, so bekommtn man folgende Optionen angezeigt:

Optionen:

-enterprise -- Verwendet den Unternehmensregistrierungs-Zertifikatspeicher auf dem lokalen Computer
-user -- Verwendet HKEY_CURRENT_USER oder Zertifikatspeicher.
-GroupPolicy -- Gruppenrichtlinien-Zertifikatspeicher verwenden

Verwenden Sie die Option -GroupPolicy für Zertifikate, die per Gruppenrichtlinie verteilt wurden. Der richtige Speicher ist wichtig, da Certutil Ihnen sonst zwar Vollzug vermeldet, aber die Zertifikate nicht löscht. Weiterhin benötigen Sie den Thumbprint (Daumenabdruck oder Checksumme) des zu entfernenden Zertifikats. Den erhalten Sie über Powershell:

Get-Childitem Cert:LocalMachine\root 

In diesem Fall zeigen wir die Zertifikate der Stammzertifizierungsstellen an. Die erste Zeile gibt Ihnen den Tumbprint aus. Versuchen Sie nun, das Zertifikat zu entfernen:

Get-Childitem Cert:LocalMachine\root | where-object Thumbprint -eq "<Ihr Thumbprint>" | remove-item -force

Klappt das nicht, ist das Zertifikate vermutlich über eine Gruppenrichtlinie verteilt worden. Jetzt hilft Ihnen Certutil:

Get-Childitem Cert:LocalMachine\root
certutil -delstore -Grouppolicy <Thumbprint>

Alternativ können Sie auch die Pipeline verwenden, das sieht aber in diesem Fall nicht so schön aus:

Get-Childitem Cert:LocalMachine\root | where-object Thumbprint -eq "<Ihr Thumbprint>" | foreach-object { certutil -delstore -Grouppolicy $_.Thumbprint }

 

 

Dateien restlos entfernen und Festplatten rückstandslos löschen mit Windows Bordmitteln

$
0
0

Immer wieder liest man den Mythos, dass man eine Festplatte 37 mal überschreiben muß, bevor die Daten vollständig gelöscht sind. In der aktuellen c´t 13/2016 gibt es dazu einen sehr guten Artikel, der die Hintergründe dazu beschreibt. Das Fazit der Artikelserie lautet: Bei alten MFM-Festplatten, bei denen die Datensektoren der Festplatten noch so groß waren wie Pfannkuchen, war eine Datenwiederherstellung mit den enstprechenden Werkzeugen in der Tat noch möglich. Bei aktuellen magnetischen Datenträgern haben sich die Aufzeichnungsverfahren aber maßgeblich verändert, und auch Datenrettungsunternehmen sind mit Ihren Werkzeugen nicht in der Lage, einmal überschriebene Daten wiederherzustellen. Ach das BSI und das amerikanische Pendant NIST geben als Richtlinie inzwischen heraus, dass eine einfache Überschreibung reicht, um Daten rückstandlos zu entfernen.

Kommen wir nun dazu, wie die Datenlöschung am einfachsten auszuführen ist. Windows bietet dazu 2 Bordmittel an.

Zum Löschen von einzelnen Dateien oder Partitionen auf der Festplatte bietet sich das Tool cipher.exe an. Es ist das Tool zur Kommandozeilensteuerung von EFS (Encrypted File System) und bietet den Schalter /w, mit dem man einzelne Dateien, Ordner oder aber auch ganze Partitionen löschen kann. Um den Ordner c:\Temp\geheim zu löschen und zu überschreiben, geben Sie hierfür ein:

Cipher.exe /w c:\Temp\geheim

Die Löschung kann eine Weile dauern, da die Daten in 3 Durchgängen mit 0, dann mit 1 und anschliessend wieder mit 0 überschrieben werden. Um die ganze Partition zu löschen, geben Sie nur Laufwerksbuchstabe: ein:

Cipher.exe /w d:

Wenn Sie die ganze Festplatte löschen wollen, nutzen Sie den Befehl diskpart. Diskpart ist ein "Menügeführtes" Tool. Geben Sie zuerst Diskpart ein, wählen Sie dann mit Select Disk <0> die Festplatte aus, und geben Sie danach CLEAN ALL ein. Die Option ALL sorgt dafür, dass die Platte einmal überschrieben wird - ansonsten wird nur der Bootbereich und die Partitionstabelle überschrieben. CLEAN ALL führt einen einmaligen Überschreib-Vorgang mit 0 aus, der aber vollkommen ausreicht, um die Daten unwiederbringlich zu löschen.

Diskpart
List Disk
Select Disk <Nummer>
Clean All

Benutzerprofilkompatibilität in WIndows 7, 8 und 10

$
0
0

Auch das Benutzerprofil von Windows 10 ist wieder nicht mit den Vorgängerversionen kompatibel. Aber Microsoft hat vorgesorgt. Mit Windows 7 hat Microsoft zum ersten mal eine neue Verion des Benutzerprofils eingeführt, um zu verhindern, dass Benutzer mit servergespeicherten Profilen nicht beim Wechsel zwischen Betriebssystemversionen (z.B. auf RDP-Servern) ihr Profil zerschiessen. Dafür legt Windows 7 einen eigenen Profilordner mit der Endung .V2 an. Windows 8 und Windows 8.1 verwenden standardmässig das gleiche Verzeichnis wie Windows 7, nämlich .V2. Man kann allerdings aktivieren, dass auch Windows 8 (.V3) und Windows 8.1 (.V4) sich in eigenen Unterordern schreiben. Installieren Sie hierfür je nach Betriebssytem eines der beiden Hotfixes:

Für Windows 8 das in KB2887239 beschriebene.
Für Windows 8.1 das in KB2887595 beschriebene Hotfix Rollup. 

Danach setzen Sie den folgenden Schlüssel in der Registry:

Schlüssel: HKEY_LOCAL_MACHINE\System\CurrentControlset\Services\ProfSvc\Parameters
Name: UseProfilePathExtensionVersion
Wert: 1

Alternativ können Sie dieses Feature auch über Gruppenrichtlinien Einstellungen (Group Policy Preferences) setzen. 

Mit Windows 10 hat Microsoft dieses Schema jetzt beibehalten. Windows 10- bzw. Windows Server 2016-Clients legen für Benutzerprofile automatisch einen Profilordner mit der Endung .V5 an. Alternativ bleibt nach wie vor, UE-V zur Profil-Synchronisation zu verwenden.


virtuelle Hyper-V Maschinen mit dem NAT-Switch verwenden - byebye Router-VM!

$
0
0

Dank Docker gibt es in der aktuellen Preview von Windows 10 und in der Rosetta-Jubiläums-Ausgabe, die Ende Juli erscheint, endlich die Möglichkeit, virtuelle Maschinen in einem isolierten, privaten Netzwerk per NAT mit dem physikalischen Netzwerk zu verbinden, ohne eine Router-VM installieren zu müssen. Der NAT-Switch wurde notwendig, um per Docker bereitgestellte Anwendungen mit den Netzwerk zu verbinden. Und so richtet man einen NAT-Switch ein: 

Legen Sie zuerste mit Hyper-V einen neuen internen VM-Switch an. In früheren Versionen von Windows 10 gab es einen speziellen NAT-Switch, aber der ist zugunsten des internen Switches wieder gewichen:

$NatSwitch = New-VMSwitch -SwitchName Nat -SwitchType Internal

Als nächstes benötigen wir eine Gateway-Adresse für das interne Netzwerk, die wir an den Switch binden. Ein interner Switch legt automatisch auch eine interne virtuelle Netzwerkkarte an. An diese wird die Gateway-IP gebunden. Das folgende Script fragt zunächst den zum Switch gehörenden Netwerkadapter ab. Das passiert in zwei Schritten: Erst wird die virtuelle Repräsentation mit Get-VMNetworkadapter abgefragt, und dann wird die dazugehörige physikalische Netzwerkkarte abgefragt. Es handelt sich dabei um dasselbe Gerät, aber mit zwei unterschiedlichen Cmdlets abgefragt. Diesen umständlichen Weg gehen wir, weil get-Vmnetworkadapter uns den Interface-Index nicht zurück liefert, den wir benötigen, um das NAT-Netzwerk einzurichten: 

$natNetworkAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $NatSwitch.Name
$networkAdapter = Get-NetAdapter | Where-Object -FilterScript {
     $_.deviceid -eq $natNetworkAdapter.DeviceId
}

Im nächsten Schritt legen wir die Gateway-IP Adresse an und binden Sie an die virtuelle Netzwerkkarte des Switches:

New-NetIPAddress -IPAddress 10.1.255.254 -PrefixLength 16 -InterfaceIndex $networkAdapter.InterfaceIndex
New-NetNat -Name NatNetwork -InternalIPInterfaceAddressPrefix '10.1.0.0/16' -Verbose

Nun müssen Sie nur noch Ihre VMs an den neuen Switch binden, und schon haben Ihre VMs Zugriff auf Ihr Netzwerk, ohne dass Sie einen externen Switch erstellen oder eine Router-VM anlegen mußten. Der NAT-Switch kann aber auch Datenverkehr in das interne Netzwerk leiten. Verwenden Sie hierzu das Cmdlet Add-NetNatStaticMapping:

Add-NetNatStaticMapping -NatName Nat -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 10.1.100.200 -InternalPort 80 -ExternalPort 80

Zum Anlegen des Switches habe ich eine kleine Funktion gebaut, die das Anlegen deutlich vereinfacht:

#requires -Version 3 -Modules Hyper-V, NetAdapter, NetNat, NetTCPIP

<#

.Synopsis

Creates a NAT-Switch in Windows 10

.DESCRIPTION

This Script can create a NAT-Switch for you. Just Enter the internal IP,

Subnet-Prefix and a Name for the Switch, and your done! The NAT-Switch requires

Windows 10 Anniversary Edition (Redstone) and Hyper-V activated.

The NAT-Switch can connect your VMs from internal Networks with the physical Network

without a dedicated Router-VM

.EXAMPLE

new-natswitch -IpAddress 192.168.10.1 -prefix 24

Creates a new Switch with Name NAT and connects it to the internal Network 192.168.10.0

.EXAMPLE

new-natswitch -SwitchName ConnectExternal -IpAddress 192.168.10.1 -prefix 24

Creates a new Switch with Name ConnectExternal and connects it to the internal Network 192.168.10.0

.LINK

https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/user_guide/setup_nat_network

https://technet.microsoft.com/de-de/library/dn283352%28v=wps.630%29.aspx?f=255&MSPPError=-2147217396

http://www.indented.co.uk/2010/01/23/powershell-subnet-math/

#>

function New-Natswitch

{

    param

    (

        # Name of the virtual Switch.

        [String]

        [validateScript({

                    -not ( Get-VMSwitch -Name $_ )

        })]

        $SwitchName = 'Nat',

        # Internal IP-Address of the Switch (= internal Gateway)

        [IPAddress]

        [Parameter(Mandatory)]

        $IpAddress,

        # The Subnet-Mask in CIDR-Form

        [string]

        [ValidateRange(8,30)]

        [Parameter(Mandatory)]

        $prefix,

       

        # The Name of the virtual network. If not set, the network will be named like the Nat-Switch

        [string]

        $NetNatName

    )

    If ( Get-NetNat -ea SilentlyContinue )

    {

        throw 'You can only have one NatNetwork per Host'

    }

    If ( -not $NetNatName )

    {

        $NetNatName = $SwitchName

    }

    # Regular Expression needed to split 32 Bit into 8 Bit Octetts

    $octettRegex = '(?<=\G\d{8})(?=.)'

    # Convert Prefix into Bit-Representation

    for ($x = 1; $x -le 32; $x++)

    {

        if ($x -le $prefix)

        {

            $bit = '1'

        }

        else

        {

            $bit = '0'

        }

        [string]$subnetmask += $bit

    }

    # Convert IP into Binary Representation

    $ipOctettList = $IpAddress.IPAddressToString -split '\.' | foreach-object { ([convert]::ToString($_,2)).padleft(8,'0') }

    $ipBinary = $ipOctettList -join ''

    # Logical AND (band) calculates Subnet from IP

    $SubnetBinary = [convert]::ToUInt64($ipBinary,2) -band [convert]::ToUInt64($subnetmask,2) |

        ForEach-Object { ([convert]::ToString($_,2)).padleft(32,'0') }

    # Convert Binary IP back into Decimal IP Representation

    $subnetIP = ($SubnetBinary -split $octettRegex | ForEach-Object { [convert]::ToUInt64($_,2) }) -join '.'

    # Create the switch

    try

    {

        $NatSwitch = New-VMSwitch -SwitchName $SwitchName -SwitchType Internal

    }

    catch

    {

        'Failed to create Virtual Switch: {0}' -f $_.Exception

        break

    }

   

    $natNetworkAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $NatSwitch.Name

    $networkAdapter = Get-NetAdapter | Where-Object -FilterScript {

        $_.deviceid -eq $natNetworkAdapter.DeviceId

    }  

   

    try

    {

        $null = New-NetIPAddress -IPAddress $IpAddress.IPAddressToString -PrefixLength $prefix -InterfaceIndex $networkAdapter.InterfaceIndex -EA Stop

        New-NetNat -Name $NetNatName -InternalIPInterfaceAddressPrefix "$subnetIP/$prefix" -EA Stop

    }

    catch

    {

        'Fehler: {0}' -f $_.Exception

        "`nNatswitch konnnte nicht angelegt werden."

        $NatSwitch | Remove-VMSwitch -Force      

    }

 

Das ganze geht auch ein bißchen übersichtlicher mit Subroutinen, aber dann haben wir nicht mehr die ganze Funktionalität in einem Script. Mehr dazu im nächsten Tipp. 

Powershell-Skripte ausführen trotz Applocker und Ausführungsrichtlinien

$
0
0

Die Windows-Powershell ist ein sehr mächtiges Werkzeug, und wie alle mächtigen Werkzeuge kann man Ihre Funktionen für gute wie für schlechte Dinge anwenden. Daher versuchen viele Unternehmen, die Ausführung von Powershell zu verhindern. Das die Ausführungsrichtlinie, die die Skriptausführung einschränken kann, kein echtes Hinternis ist, hat sich inzwischen herumgesprochen. Tatsächlich scheint der Stand der Dinge zu sein, dass man mit Windows Bordmitteln nur mit Applocker (ab Windows 7 Enterprise oder Windows 8.1 / Windows 10 Pro) einen ansatzweise hinreichenden Schutz vor der Ausführung von Powershell erreichen kann. Versuchen Sie aber gar nicht erst, mit Skriptregeln herum zu spielen - Skriptregeln verhindern das Ausführen von Skripten, aber nicht den Start von Powershell. Und da man in Powershell jedes Skript auch von Hand eingeben kann, erreicht man mit dem Verhindern von Skripten gar nichts. Man könnte jetzt noch argumentieren, dass lange Skripte nicht von Hand übertragen werden können, oder dass ein Hacker ohne physikalischen Zugriff auf den Server die Skripte nicht von Hand in die Konsole übertragen kann. Allerdings läßt sich Powershell auch manuell mit dem Parameter "-Command" starten. Und es ist sehr einfach, ein Skript von der Kommandozeile aus einzulesen und einfach über den Standard-Ausgabestrom an die Powershell.exe weiterzuleiten.

get-content c:\temp\meinSchadcode.txt | powershell.exe -command -

Hier fehlt im Übrigen nichts, es handelt sich in der Tat um einen Bindestrich hinter dem -Command. Der Bindestrich bewirkt, dass das auszuführende Kommando aus dem Ausgabestrom gelesen wird. Dadurch muß der Schadcode sich noch nicht einmal in einer .ps1-Datei befinden - Powershell.exe unterbindet die Ausführung von anderen Dateiendungen normalerweise.

Freie Laufwerke finden mit Powershell

$
0
0

Zum Vergeben eines Laufwerksbuchstaben muß man zuerst einmal evaluieren, welchen Laufwerksbuchstabe frei ist. Es gibt eine Reihe Ansätze, aber dieser hier ist für Lernzwecke ganz interessant. Die folgende Funktion wandelt die Asciicodes der Buchstaben C (Ascii 67) bis Z (Ascii 90) in Buchstaben um. Die Buchstaben werden der Reihe nach in einer Foreach-Schleife mit Test-Path gegen die vorhandenen Pfade überprüft. Sobald Test-Path False zurück gibt, wird die Schleife per "break" abgebrochen und der gefundene Buchstabe zurück gegeben. 

Interessant in diesem Zusammenhang ist auch die Invertierung der Suche. Um beim letzten Buchstaben zu beginnen, wird einfach der Startbuchstabe auf Z gesetzt und die Auflistungsreihenfolge umgedreht ( $Counter..67 bzw. $Counter..90). Allerdings ist der Default-Wert für den Startbuchstaben auf C gesetzt, so dass eine Invertierung der Suche ohne setzen des Startbuchstabens normalerweise kein Ergebnis liefert. Eine Lösung bietet die automatische Variable $PSBoundParameter. Diese Variable wird automatisch erstellt, wenn beim Aufruf einer Funktion Übergabeparameter vom Benutzer verwendet werden. Die Methode Containskey() überprüft, ob ein Parameter vorhanden ist oder nicht. 

function get-freedrive

{

  <#

      .SYNOPSIS

      Get-Freedrives lists the first free driveletter in the alphabet.

      .DESCRIPTION

      Get-Freedrive can be used to test for the first available free driveletter. The Parameter $inverse searches backwards through the alphabet.

      .EXAMPLE

      get-freedrive -inverse -startLetter Z

      Starts the search with letter z searching backwards. Returns a character.

      .NOTES

      Place additional notes here.

      www.netz-weise-it.training/weisheiten/

  #>

  [cmdletbinding()]

  param(

   

    # The letter to start the search from - default is C or Z, if -inverse is chosen

    [char]$startLetter = 'C',

   

    # Inverse forces a backwards search through the alphabet

    [switch]$inverse

  )

  # Legt bei inverser Suche den Startletter auf Z fest, wenn kein Startbuchstabe angegeben wurde.

  If ( -not ( $PSBoundParameters.ContainsKey("Startletter") ) -and ( $inverse ) )

    { $startLetter = 'Z' }

  #

  [int]$Counter = ([Convert]::ToByte( $startLetter ))

  if ( $inverse )

    { $Chararray = $Counter..67 }

  Else { $Chararray = $Counter..90 }

  foreach ( $letter in $CharArray )

  {

    if ( -not ( Test-Path -Path ( [Char]$letter + ':\')))

    {

      [char]$letter

      break

    }

  }

}

Die Existenz einer OU testen mit Powershell

$
0
0

Leider bietet das Powershell AD-Modul keine Möglichkeit, auf das Vorhandensein einer Organizational Unit zu testen. Diese Funktion lässt sich aber einfach nachrüsten. 

Grundsätzlich kann man die Existenz einer OU testen, indem man einfach das Cmdlet Get-OrganizationalUnit verwendet. Prüft man die Abfrage in einer IF-Bedingung, wird der Scriptblock des IF ausgeführt, wenn die OU existiert. Das Ganze hat allerdings einen Haken, denn Get-ADOrganizationalUnit bricht die Skriptverarbeitung mit einem unbehandelten Fehler ab, wenn die OU nicht existiert.

If ( Get-ADOrganizationalUnit -Identity "OU=test,DC=Netz-Weise,DC=DE" ) { $true }
get-adorganizationalUnit : Directory object not found

Dieses Verhalten kann man sich zunutze machen, indem man die Ausführung des Get-ADOrganizationalUnit mit Try-Catch ausführt. Wird ein unbehandelter Fehler ausgeführt, wird die Catch-Block aufgerufen und ausgeführt. In diesem muß man jetzt nur noch einen $False zurück liefern. 

function Test-ADOrganizationalUnit

{

  <#

      .SYNOPSIS

      Test Existance of an Organizational Unit and Returns True of False.

      .DESCRIPTION

      The Function is testing an OU-Path. If the OU exists, the function returns $true, else $false.

      It can be used inside an IF-Statement.

      .EXAMPLE

      Test-ADOrganizationalUnit -OU "OU=test,DC=Netz-Weise,DC=DE"

      Tests the given OU-path and returns true, if the OU exists, else false.

      .LINK

      https://www.netz-weise-it.training/weisheiten/tipps/item/381-die-existenz-einer-ou-testen-mit-powershell.html

      The first link is opened by Get-Help -Online Test-ADOrganizationalUnit

      .INPUTS

      List of input types that are accepted by this function.

      .OUTPUTS

      List of output types produced by this function.

  #>

  [CmdletBinding()]

  param(

    [ValidateNotNullOrEmpty()]

    $OU

  )

  Try

  {

    IfGet-ADOrganizationalUnit -Identity $OU )

    {

      $true

    }

  }

  Catch

  {

    $false

  }

 

Der Aufruf der Funktion sieht dann so aus: 

Test-ADOrganizationalUnit -OU "OU=test,DC=Netz-Weise,DC=DE"

Details von GPO-Backups anzeigen mit Powershell

$
0
0

Wenn Sie ein Gruppenrichtlinienbackup erstellen, wird für jede GPO ein eigener Sicherungsordner angelegt. Der Sicherungsordner trägt allerdings nicht den Namen der GPO, sondern es wird für jede Sicherung eine eigene GUID erstellt.

Wenn Sie die Sicherung in der Domäne wiederherstellen möchten, in der Sie die Sicherung angelegt haben, ist das nicht problematisch, da die GPMC Ihnen über "Manage Backups" auf den Container "Group Policy Objects" die Details Ihrer Backups anzeigt. Wenn Sie die Backups allerdings auf eine andere Domäne übertragen wollen, fehlen Ihnen diese Informationen. Vor allem bei umfangreichen Backups hilft dann nur eine gute Dokumenation oder die folgenden beiden Funktionen, die einen Backup-Ordner einlesen und die relevanten Informationen auslesen können.

ConvertFrom-GPVersion konvertiert die 32-Bit Versionsnummern der Computer- bzw. Benutzerkonfiguration in einen dezimalen Versionswert. Sie wird von Get-GPOBackupInfoFromXML verwendet, um die korrekte Version der User-bzw. Computerkonfiguration zu berechnen. Beide Funktionen sind auch Bestandteil des aktuellen GPHelper-Powershellmoduls

function ConvertFrom-GPVersion

{

  <#

      .SYNOPSIS

      Converts the Group Policy Version-Number into a Computer-/User Version Number

      .EXAMPLE

      ConvertFrom-GPVersion -VersionNumber 65537

      converts the 32-Bit Represenation of the Version-Number into a 16-Bit Value

      .NOTES

      Group-Policys Version-Number for Computer- and Userversion are represented in one 32-Bit Value. This Function converts

      the number back into a 16-Bit Value.

  #>

 

  [CmdletBinding()]

  param(

    [Parameter(Mandatory=$true)]

    [ValidateRange(0,4294967295)]

    [int]$VersionNumber

  )

 

  [regex]$regex = '(\d{16})?'

 

  If ( $VersionNumber -lt [int]65536 )

  {

    $VersionBinary = ([convert]::ToString($VersionNumber,2)).padleft(16,'0')

    Write-Verbose -Message $VersionBinary

    [convert]::ToUInt64($VersionBinary,2)

  }

  Else

  {

    $VersionBinary = ([convert]::ToString($VersionNumber,2)).padleft(32,'0')

    Write-Verbose -Message $VersionBinary

    $Versions =$regex.Matches($VersionBinary) | Select-Object -ExpandProperty Value -skip 1 -First 1

    [convert]::ToUInt64($Versions,2)

  }

}

function Get-GPOBackupInfoFromXml {

  <#

      .SYNOPSIS

      Gets the relevant Information about GPO-Backups from a Powershell Backup Directory

      .DESCRIPTION

      If you want to find out which backups are in a dedicated Group Policy Backup Folder

      and when they are taken, this functions returns all the relevant Information

      .EXAMPLE

      Get-GPOBackupInfoFromXml -backuppath c:\gpobackup

      Parses all backup.xml-files in the directory and returns Infomation about the Backups.

  #>

  [CmdletBinding()]

  param(

    [parameter(mandatory=$true,

        position=0,

    ValueFromPipelineByPropertyName=$true)]

    [ValidateScript({ Test-path -Path $_ -PathType Container })]

    [Alias('Fullname')]

    [string]$backuppath

  )

  process$backupfiles = get-childitem -Path $backuppath\backup.xml -Recurse

    Foreach ( $BackupFileItem in $backupfiles )

    { 

      [xml]$backupinfo = get-content -Path $BackupFileItem.Fullname -ReadCount 0 -Encoding UTF8

      $comment = Get-Content -Path ( join-path -Path $BackupFileItem.Directory.FullName -ChildPath 'DomainSysvol\gpo\GPO.cmt' ) -ErrorAction SilentlyContinue -Encoding Unicode

      $gpoProperties = [ordered]@{

        BackupTime = ( get-date -Date $BackupFileItem.CreationTime -Format g )

        name = $backupinfo.GroupPolicyBackupScheme.GroupPolicyObject.GroupPolicyCoreSettings.DisplayName.InnerText

        GPOGUID = $backupinfo.GroupPolicyBackupScheme.GroupPolicyObject.GroupPolicyCoreSettings.ID.InnerText

        BackupGUID = $BackupFileItem.Directory.Name

        Options = $backupinfo.GroupPolicyBackupScheme.GroupPolicyObject.GroupPolicyCoreSettings.Options.InnerText

        UserVersion = ConvertFrom-GPVersion -VersionNumber ( $backupinfo.GroupPolicyBackupScheme.GroupPolicyObject.GroupPolicyCoreSettings.UserVersionNumber.InnerText.ToString())

        MachineVersion = ConvertFrom-GPVersion -VersionNumber ( $backupinfo.GroupPolicyBackupScheme.GroupPolicyObject.GroupPolicyCoreSettings.MachineVersionNumber.InnerText.ToString())

        Comment = $comment

      }

      $GPO = New-Object -TypeName PSCustomObject -Property $GPOProperties

      $GPO

    }

  }

Viewing all 119 articles
Browse latest View live