Haikos Blog Blog von Haiko Hertes zu allen Themen rund um Microsoft und Datacenter

27Mrz/190

Azure / PowerShell – Azure SQL Performance Empfehlungen per PowerShell abholen und verteilen

Azure und insbesondere Azure SQL ist klasse - es nimmt einem viele Dinge der täglichen Verwaltung ab, einiges davon sogar automatisch. Klar, das hat seinen Preis, immerhin ist Azure SQL nicht ganz billig, aber wenn man es schon bezahlt, dann kann man auch seine Fähigkeiten nutzen. Eine davon ist, automatisch anhand der Nutzung einer Datenbank Empfehlungen für die Leistungsoptimierung zu geben. Diese kann man sich im UI bzw. dem Azure Portal anschauen. Dazu öffnet man entweder links im Blade den Punkt "Recommondations" unterhalb von "Intelligent Performance" oder den Punkt "Performance" auf der Main-Page bei den Notifications:

Dort sieht man dann einige Empfehlungen aufgeführt (vorausgesetzt, Azure hat etwas gefunden, was wiederum eine regelmäßige Nutzung der Datenbank voraussetzt):

Diese Daten kann man sich auch automatisch abrufen und auf Wunsch dann z.B. an die Entwickler verteilen. Dazu bediene ich mich einfach der PowerShell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$ErrorActionPreference = "Stop"
$SubscriptionId = "YOUR_SUBSCRIPTION_ID"
 
function Get-SQLServerRecommendations()
{
    # Define the resource types
    $resourceTypes = ("Microsoft.Sql/servers/databases")
    $advisors = ("CreateIndex", "DropIndex","DbParameterization","SchemaIssue");
    $results = @()
 
    # Loop through all subscriptions
 
    $rgs = Get-AzureRmResourceGroup
 
    # Loop through all resource groups
    foreach($rg in $rgs) {
        $rgname = $rg.ResourceGroupName;
 
        # Loop through all resource types
        foreach($resourceType in $resourceTypes) {
            $resources = Get-AzureRmResource -ResourceGroupName $rgname -ResourceType $resourceType
 
            # Loop through all databases
            # Extract resource groups, servers and databases
            foreach ($resource in $resources) {
                $resourceId = $resource.ResourceId
                if ($resourceId -match ".*RESOURCEGROUPS/(?<content>.*)/PROVIDERS.*") {
                    $ResourceGroupName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*SERVERS/(?<content>.*)/DATABASES.*") {
                    $ServerName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*/DATABASES/(?<content>.*)") {
                    $DatabaseName = $matches['content']
                } else {
                    continue
                }
 
                # Skip if master
                if ($DatabaseName -eq "master") {
                    continue
                }
 
                # Loop through all Automatic tuning recommendation types
                foreach ($advisor in ($advisors -notmatch "SchemaIssue")) {
                    $recs = Get-AzureRmSqlDatabaseRecommendedAction -ResourceGroupName $ResourceGroupName -ServerName $ServerName  -DatabaseName $DatabaseName -AdvisorName $advisor
                    foreach ($r in $recs) {
                        if ($r.State.CurrentValue -eq "Active") {
                            $object = New-Object -TypeName PSObject
                            $object | Add-Member -Name 'SubscriptionId' -MemberType Noteproperty -Value $subscriptionId
                            $object | Add-Member -Name 'ResourceGroupName' -MemberType Noteproperty -Value $r.ResourceGroupName
                            $object | Add-Member -Name 'ServerName' -MemberType Noteproperty -Value $r.ServerName
                            $object | Add-Member -Name 'DatabaseName' -MemberType Noteproperty -Value $r.DatabaseName
                            $object | Add-Member -Name 'Advisor' -MemberType Noteproperty -Value $advisor
                            $object | Add-Member -Name 'Script' -MemberType Noteproperty -Value $r.ImplementationDetails.Script
                            $results += $object
                        }
                    }
                }
            }
        }
    }
    Return $results
}
 
$AzurePasswordSecure = ConvertTo-SecureString "$($YOUR_AZURE_PASSWORD)" -AsPlainText -Force
$AzureCredentials = New-Object System.Management.Automation.PSCredential ("$YOUR_AZURE_USER", $AzurePasswordSecure)
Connect-AzureRmAccount -Credential $AzureCredentials | Out-Null
Select-AzureRmSubscription -Subscription $SubscriptionId | Out-Null
 
$Recommendations = Get-SQLServerRecommendations
$table = $Recommendations | Sort-Object DatabaseName,Advisor | Format-Table Databasename,Advisor,Script -AutoSize -Wrap
Write-Output $table
 
$head = "<style>
td {background-color:lightgrey;}
table {width:100%;}
th {font-size:14pt;background-color:lightblue;}
</style>
<title>SQL Server performance recommendations</title>"
 
[string]$html = $Recommendations | ConvertTo-Html -Property Databasename,Advisor,Script -Body "<h1>Azure SQL Server automatic tuning recommendations for $stage</h1>Auto-generated by PUT_SOMETHING_HERE<br><br>" -Head $head
 
Send-MailMessage -Body $html -SmtpServer YOUR.SMTPSERVER.COM -From sender@domain.com -To recipient@domain.com -Subject "MS SQL Recommendations - $(Get-Date -Format "yyyy-dd-MM HH:mm:ss")" -BodyAsHtml

Dieses Script wiederum kann man dann z.B. per Jenkins regelmäßig auslösen. Oder alternativ ein Azure Automation Runbook dafür anlegen... Viel Spaß beim Ausprobieren!

Die Mails sehen dann in etwa so aus:

5Jul/150

SCCM 2012 R2: Office 2013 (und andere) automatisiert ausrollen

Will man Office 2013 (oder eine andere Version) über den System Center Configuration Manager 2012 R2 (oder auch ältere Versionen) automatisch und ohne Benutzerinteraktion installieren, so bedarf es ein paar kleiner Kniffe.

Den gesamten Ablauf, wie hier vorzugehen ist, möchte ich im Folgen aufzeigen. Wichtig ist, dass man als Quelle eine Volumenlizenz-DVD benötigt. Diese erkennt man am “admin”-Ordner auf der DVD im Stammverzeichnis.

Vorbereiten der automatisierten Installation

Zunächst muss der Inhalt der Office 2013 DVD auf ein freigegebenes Verzeichnis kopiert werden, in meinem Fall der Ordner “Sources”, welcher auf dem SCCM-Standalone-Server existiert und als “\SOURCES” freigegeben ist:

office1

Anschließend wird das “Microsoft Office-Anpassungstool” (engl.: “Office Customization Tool”) über den Aufruf der setup.exe mit Parameter gestartet:

setup.exe /admin

office2

Hier wird nun eine neue Setupanpassungsdatei erstellt:

office3

Außerdem lässt sich das künftige Office-Dateiformat wählen:

office3b

Nun können diverse Anpassungen am künftigen Setup gemacht werden. Zu Beginn kann man z.B. die Unternehmensdaten hinterlegen:

office4a

Außerdem muss die Lizenzierung sowie das Verhalten der Benutzeroberfläche festgelegt werden:

office4b

Hier wird dem Lizenzvertrag zugestimmt, die Anzeigeebene auf “Grundlegend” gestellt sowie die beiden unteren Checkboxen angewählt und die obere Checkbox abgewählt.

In den Setup-Eigenschaften wird noch mit einer neuen Eigenschaft “SETUP_REBOOT” und deren Wert “Never” ein Neustart nach dem Setup unterdrückt:

office5

Um den “Welcome-Screen” beim ersten Start zu deaktivieren ist unter “Benutzereinstellungen ändern” / “Microsoft Office 2013” / “Datenschutz” / “Trust Center” der Eintrag “Bestätigungs-Assisten […] deaktivieren” auf  “Aktiviert” zu setzen:

office6

Weiterhin können bei Bedarf weitere Anpassungen gemacht werden, z.B. die zu installierenden Programmbestandteile:

office7

Abschließend werden die Einstellungen in einer neuen Datei im “Updates”-Pfad unterhalb des Stamm-Pfades der Office-Installation abgespeichert:

office8

office9

Erzeugen der SCCM-Anwendung

Nun da die MSP-Datei erstellt wurde, kann im SCCM ein neues Anwendungs-Objekt für Office 2013 erzeugt werden:

office10

Dabei ist “Windows Installer (MSI-Datei)” als Typ auszuwählen und über den “Durchsuchen”-Dialog die proplusww.msi unterhalb des “proplus.ww”-Ordners zu öffnen:

office11office12

office13office14

Unter den “Allgemeinen Informationen” können bzw. müssen einige Informationen hinterlegt bzw. geändert werden. So kann man weitere Produkt-Details zur Installation angeben. In jedem Fall muss man im Feld “Installationsprogramm” die MSI gegen den Eintrag “setup.exe” austauschen und sicherstellen, dass als “Installationsverhalten” der Eintrag “Für System installieren” ausgewählt ist.

office15

office16

Anschließend muss der “Bereitstellungstyp” des neuen Anwendungsobjektes geöffnet werden, da hier noch Änderungen vorgenommen werden müssen:

office17

Auf dem Reiter “Inhalt” muss im Pfad des “Inhaltsort” abschließende “\proplus.ww” entfernt werden…

office18

… und auf dem Reiter “Programm” im Feld “Deinstallationsprogramm” statt MSI-Weges einfach nur “Setup.exe /uninstall” eingetragen werden:

office19

Bei Bedarf können auf dem Reiter “Anforderungen” noch selbige definiert werden. Da ich hier eine 64-Bit-Installation verwendet habe, ist natürlich auch das entsprechende OS nötig:

office20

Ist man damit fertig, kann man das Office-Anwendungs-Objekt jetzt wie gewohnt verteilen und anschließend für die gewünschte (idR. extra dafür neu anzulegende) Gerätesammlung bereitgestellt werden…

18Dez/140

AutoAdminLogon für Windows Server 2012 R2 und andere OS

Manchmal besteht der Wunsch, auf einem Windows-System eine automatische Anmeldung nach dem (Neu)Start durchzuführen. Dies ist mit sehr einfachen Mitteln möglich und funktioniert sowohl bei Client- als auch Server-Betriebssystemen, auch bei älteren. Nötig ist dazu nur der Zugriff auf die Registry und ein passendes Benutzerkonto.

Als erstes wird der Registrierungseditor mittels “regedit.exe” geöffnet:

autoadminlogon1

Dort muss zu dem Schlüssel unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon navigiert werden.

Abschließend sind folgende Schlüssel nötig (alle als Zeichenfolge, REG_SZ)

  • AutoAdminLogon = “1”
  • DefaultUserName = BENUTZER
  • DefaultPassword = PASSWORT
  • DefaultDomainName = DOMÄNE

So etwa wie im Screenshot…

autoadminlogon2

Das war es schon gewesen. Beim nächsten Neustart ist die automatische Anmeldung aktiv…