dbatools – Migration der SQL Agent Backup Jobs

Man kann denken was man will, aber manchmal muss man über seinen Schatten springen… in der Regel bin ich ein Verfechter des SQL Server eigenen Backups, egal ob Backup to Disc, Backup to URL oder Backup to NetworkShare, aber hier musste ich (leider) nachgeben und die Sicherung mittels 3rd-Party-Tools einrichten. Gesagt… getan…

Bei dem Kunden hatten wir sowieso schon alles auf 3rd-Party-Backup umgestellt, aber nicht auf Backup-Server initiertes Sicherungen, sondern SQL Server initiert. Der SQL Server Agent startet also das jeweilige Backup als Kommandozeilen-Aufruf. Hierzu musste ich also die Sicherungsjobs von einem existierenden Server kopieren und anpassen, sowie alle dazugehörigen SQL Server Objekte. Gestartet habe ich mittels “Create Objects to NewQuery”, erhielt aber die Fehlermeldung, dass die Mail-Komponente bzw Empfänger noch existiert bzw konfiguriert ist. Also musste ich erst die SQL-Mail-Konfiguration übernehmen, hierzu auch noch die Operator übernehmen und wenn wir schon beim Mailing sind, dann kann ich die von Brent Ozar empfohlenen SQL Agent Alerts auch gleich mit migrieren…

dbatools - die Powershell Modulsammlung für den DBA

verwendete Powershell Module – dbatools

Macht euch mal kurz Gedanken dazu, wie man die Konfiguration von SQL-Mail, Operatoren und Custom-Alerts ohne großen Aufwand von einem SQL Server auf den anderen migrieren kann, also ich meine mit Bordmitteln… das ist zwar nicht wirklich viel Aufwand, aber doch etwas mehr als 5 Minuten. Also was liegt näher als sich intensiver mit den dbatools zu beschäftigen…
Mittels “Copy-SqlDatabaseMail” kann man die SQLMail-Konfiguration übernehmen, mit “Copy-SqlOperator” die eingerichteten Operatoren migrieren, weiter geht es mit “Copy-SqlAlert” und zum Schluss noch die Jobs kopieren. Ist doch gar nicht so viel 😉

Copy-SqlDatabaseMail -Source SQLServer01 -Destination SQLServer02
Copy-SqlOperator -Source SQLServer01 -Destination SQLServer02
Copy-SqlAlert -Source SQLServer01 -Destination SQLServer02
Copy-SqlJob -Source SQLServer01 -Destination SQLServer02 -Jobs  Full-Backup, TLog-Backup

Also ganze 4 Zeilen Powershell Code um mir die Arbeit zu erleichtern, auch dank der Vereinheitlichung der Parameter innerhalb von dbatools ist auch die Parametrisierung der einzelnen Befehle eine sehr einfache Sache und schnell und unkompliziert zu erledigen. Man kann die Nutzung von dbatools nur jedem empfehlen!

Björn arbeitet in Hamburg als Datenbank-Administrator und Head of Competence für MS SQL und mySQL. Er nimmt regelmäßig an den PASS Regionalgruppen Treffen in Hamburg, den Veranstaltungen der PASS wie SQLSaturday und SQLGrillen teil und er organisiert in Hamburg das Azure Meetup. Er interessiert sich neben den Themen rund um den SQL Server, Powershell und Azure für Science-Fiction, Snowboarden, Backen 😉 und Radfahren.

Login Migration von SQL Server 2005 auf 2008R2 inklusive Passwörtern

Gestern stand ich mal wieder vor der Aufgabe einen älteren SQL Server (SQL Server 2005) auf einen “neueren” SQL Server (SQL Server 2008 R2) zu migirieren.

Auftrag:
Kopiere bitte die Datenbanken 1-10 auf den neuen Server
Kopiere bitte alle User/Logins auf den neuen Server inkl. aller Berechtigungen

Nun kennen wir eigentlich alle diese Login-Migrations-Skripte von Microsoft => Übertragen von Benutzernamen und Kennwörtern zwischen Instanzen von SQL Server oder aus dem KB-Artikel 246133

Aber bringt der uns wirklich weiter, wenn wir funktionierende Passwörter brauchen?
Kann man mit diesen Skripten erfolgreich die Berechtigungen kopieren?

Aus meiner Erfahrung… Leider NEIN.
Also bevor ich mich wieder “schwarz” ärgere und hinterher mehr Arbeit mit dem Aufräumen und Passwörter korrigieren habe, habe ich erstmal fleißig gegoogelt, denn eigentlich müssten doch viel mehr Leute Probleme mit der Login Migration haben.

Beim Suchen bin ich über einen Beitrag “Transferring Logins to a Database Mirror” und habe es ausprobiert.
Das Skript bzw die Stored Procedure macht genau das was ich gesucht habe bzw was ich gebraucht habe.

Allerdings fand ich keine Anleitung dazu, daher schreibe ich mein Vorgehen bis zur erfolgreichen Umsetzung auf. Es ist nicht wirklich kompliziert, aber man muss sich erst einmal durch den Skript Code wühlen, um zu verstehen was erwartet wird bzw wie vorzugehen ist.

  1. mit dem Ziel-SQL-Server verbinden
  2. den Quell-SQL Server als Linked-Server einrichten
  3. das Skript ausführen, um die Stored Procedure anzulegen
  4. die Stored Procedure mit Angabe des Quell-Servers ausführen
    EXEC dba_CopyLogins @PartnerServer=<i>LinkedServer, @Debug = 0 (Default = Ausführen) / 1 (Print-Ausgabe)</i>
  5. ggf. Fehlermeldungen / Hinweise überprüfen
  6. Datenbanken und User/Logins auf Funktion prüfen

Fertig!

Das Skript lässt sich mit dem Parameter @Debug = 1 auch auf die reine Textausgabe umstellen, so dass man sich das Ergebnis erst einmal anschauen kann.
Die Stored Procedure legt die Logins mit der gleichen SID an und kopiert auch die Passwörter in korrekter Weise mit, somit dürfte es später auch keinerlei Schwierigkeiten mit “Orphaned Users” geben.

Die aktuelle Version des Skriptes findet ihr natürlich beim Autoren, hier ist der Stand vom 08.Oktober 2015 veröffentlicht.

Use master;
Go
 
If Exists (Select 1 From INFORMATION_SCHEMA.ROUTINES
			Where ROUTINE_NAME = 'dba_CopyLogins'
			And ROUTINE_SCHEMA = 'dbo')
	Drop Procedure dbo.dba_CopyLogins
Go
 
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
 
Create Procedure dbo.dba_CopyLogins
	@PartnerServer sysname,
	@Debug bit = 0
As
 
Declare @MaxID int,
	@CurrID int,
	@SQL nvarchar(max),
	@LoginName sysname,
	@IsDisabled int,
	@Type char(1),
	@SID varbinary(85),
	@SIDString nvarchar(100),
	@PasswordHash varbinary(256),
	@PasswordHashString nvarchar(300),
	@RoleName sysname,
	@Machine sysname,
	@PermState nvarchar(60),
	@PermName sysname,
	@Class tinyint,
	@MajorID int,
	@ErrNumber int,
	@ErrSeverity int,
	@ErrState int,
	@ErrProcedure sysname,
	@ErrLine int,
	@ErrMsg nvarchar(2048)
Declare @Logins Table (LoginID int identity(1, 1) not null primary key,
						[Name] sysname not null,
						[SID] varbinary(85) not null,
						IsDisabled int not null,
						[Type] char(1) not null,
						PasswordHash varbinary(256) null)
Declare @Roles Table (RoleID int identity(1, 1) not null primary key,
					RoleName sysname not null,
					LoginName sysname not null)
Declare @Perms Table (PermID int identity(1, 1) not null primary key,
					LoginName sysname not null,
					PermState nvarchar(60) not null,
					PermName sysname not null,
					Class tinyint not null,
					ClassDesc nvarchar(60) not null,
					MajorID int not null,
					SubLoginName sysname null,
					SubEndPointName sysname null)
 
Set NoCount On;
 
If CharIndex('\', @PartnerServer) &gt; 0
  Begin
	Set @Machine = LEFT(@PartnerServer, CharIndex('\', @PartnerServer) - 1);
  End
Else
  Begin
	Set @Machine = @PartnerServer;
  End
 
-- Get all Windows logins from principal server
Set @SQL = 'Select P.name, P.sid, P.is_disabled, P.type, L.password_hash' + CHAR(10) +
		'From ' + QUOTENAME(@PartnerServer) + '.master.sys.server_principals P' + CHAR(10) +
		'Left Join ' + QUOTENAME(@PartnerServer) + '.master.sys.sql_logins L On L.principal_id = P.principal_id' + CHAR(10) +
		'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
		'And P.name &lt;&gt; ''sa''' + CHAR(10) +
		'And P.name Not Like ''##%''' + CHAR(10) +
		'And CharIndex(''' + @Machine + '\'', P.name) = 0;';
 
Insert Into @Logins (Name, SID, IsDisabled, Type, PasswordHash)
Exec sp_executesql @SQL;
 
-- Get all roles from principal server
Set @SQL = 'Select RoleP.name, LoginP.name' + CHAR(10) +
		'From ' + QUOTENAME(@PartnerServer) + '.master.sys.server_role_members RM' + CHAR(10) +
		'Inner Join ' + QUOTENAME(@PartnerServer) + '.master.sys.server_principals RoleP' +
		CHAR(10) + char(9) + 'On RoleP.principal_id = RM.role_principal_id' + CHAR(10) +
		'Inner Join ' + QUOTENAME(@PartnerServer) + '.master.sys.server_principals LoginP' +
		CHAR(10) + char(9) + 'On LoginP.principal_id = RM.member_principal_id' + CHAR(10) +
		'Where LoginP.type In (''U'', ''G'', ''S'')' + CHAR(10) +
		'And LoginP.name &lt;&gt; ''sa''' + CHAR(10) +
		'And LoginP.name Not Like ''##%''' + CHAR(10) +
		'And RoleP.type = ''R''' + CHAR(10) +
		'And CharIndex(''' + @Machine + '\'', LoginP.name) = 0;';
 
Insert Into @Roles (RoleName, LoginName)
Exec sp_executesql @SQL;
 
-- Get all explicitly granted permissions
Set @SQL = 'Select P.name Collate database_default,' + CHAR(10) +
		'	SP.state_desc, SP.permission_name, SP.class, SP.class_desc, SP.major_id,' + CHAR(10) +
		'	SubP.name Collate database_default,' + CHAR(10) +
		'	SubEP.name Collate database_default' + CHAR(10) +
		'From ' + QUOTENAME(@PartnerServer) + '.master.sys.server_principals P' + CHAR(10) +
		'Inner Join ' + QUOTENAME(@PartnerServer) + '.master.sys.server_permissions SP' + CHAR(10) +
		CHAR(9) + 'On SP.grantee_principal_id = P.principal_id' + CHAR(10) +
		'Left Join ' + QUOTENAME(@PartnerServer) + '.master.sys.server_principals SubP' + CHAR(10) +
		CHAR(9) + 'On SubP.principal_id = SP.major_id And SP.class = 101' + CHAR(10) +
		'Left Join ' + QUOTENAME(@PartnerServer) + '.master.sys.endpoints SubEP' + CHAR(10) +
		CHAR(9) + 'On SubEP.endpoint_id = SP.major_id And SP.class = 105' + CHAR(10) +
		'Where P.type In (''U'', ''G'', ''S'')' + CHAR(10) +
		'And P.name &lt;&gt; ''sa''' + CHAR(10) +
		'And P.name Not Like ''##%''' + CHAR(10) +
		'And CharIndex(''' + @Machine + '\'', P.name) = 0;'
 
Insert Into @Perms (LoginName, PermState, PermName, Class, ClassDesc, MajorID, SubLoginName, SubEndPointName)
Exec sp_executesql @SQL;
 
Select @MaxID = Max(LoginID), @CurrID = 1
From @Logins;
 
While @CurrID &lt;= @MaxID
  Begin
	Select @LoginName = Name,
		@IsDisabled = IsDisabled,
		@Type = [Type],
		@SID = [SID],
		@PasswordHash = PasswordHash
	From @Logins
	Where LoginID = @CurrID;
 
	If Not Exists (Select 1 From sys.server_principals
				Where name = @LoginName)
	  Begin
		Set @SQL = 'Create Login ' + quotename(@LoginName)
		If @Type In ('U', 'G')
		  Begin
			Set @SQL = @SQL + ' From Windows;'
		  End
		Else
		  Begin
			Set @PasswordHashString = '0x' +
				Cast('' As XML).value('xs:hexBinary(sql:variable("@PasswordHash"))', 'nvarchar(300)');
 
			Set @SQL = @SQL + ' With Password = ' + @PasswordHashString + ' HASHED, ';
 
			Set @SIDString = '0x' +
				Cast('' As XML).value('xs:hexBinary(sql:variable("@SID"))', 'nvarchar(100)');
			Set @SQL = @SQL + 'SID = ' + @SIDString + ';';
		  End
 
		If @Debug = 0
		  Begin
			Begin Try
				Exec sp_executesql @SQL;
			End Try
			Begin Catch
				Set @ErrNumber = ERROR_NUMBER();
				Set @ErrSeverity = ERROR_SEVERITY();
				Set @ErrState = ERROR_STATE();
				Set @ErrProcedure = ERROR_PROCEDURE();
				Set @ErrLine = ERROR_LINE();
				Set @ErrMsg = ERROR_MESSAGE();
				RaisError(@ErrMsg, 1, 1);
			End Catch
		  End
		Else
		  Begin
			Print @SQL;
		  End
 
		If @IsDisabled = 1
		  Begin
			Set @SQL = 'Alter Login ' + quotename(@LoginName) + ' Disable;'
			If @Debug = 0
			  Begin
				Begin Try
					Exec sp_executesql @SQL;
				End Try
				Begin Catch
					Set @ErrNumber = ERROR_NUMBER();
					Set @ErrSeverity = ERROR_SEVERITY();
					Set @ErrState = ERROR_STATE();
					Set @ErrProcedure = ERROR_PROCEDURE();
					Set @ErrLine = ERROR_LINE();
					Set @ErrMsg = ERROR_MESSAGE();
					RaisError(@ErrMsg, 1, 1);
				End Catch
			  End
			Else
			  Begin
				Print @SQL;
			  End
		  End
		End
	Set @CurrID = @CurrID + 1;
  End
 
Select @MaxID = Max(RoleID), @CurrID = 1
From @Roles;
 
While @CurrID &lt;= @MaxID
  Begin
	Select @LoginName = LoginName,
		@RoleName = RoleName
	From @Roles
	Where RoleID = @CurrID;
 
	If Not Exists (Select 1 From sys.server_role_members RM
				Inner Join sys.server_principals RoleP
					On RoleP.principal_id = RM.role_principal_id
				Inner Join sys.server_principals LoginP
					On LoginP.principal_id = RM.member_principal_id
				Where LoginP.type In ('U', 'G', 'S')
				And RoleP.type = 'R'
				And RoleP.name = @RoleName
				And LoginP.name = @LoginName)
	  Begin
		If @Debug = 0
		  Begin
			Exec sp_addsrvrolemember @rolename = @RoleName,
							@loginame = @LoginName;
		  End
		Else
		  Begin
			Print 'Exec sp_addsrvrolemember @rolename = ''' + @RoleName + ''',';
			Print '		@loginame = ''' + @LoginName + ''';';
		  End
	  End
 
	Set @CurrID = @CurrID + 1;
  End
 
Select @MaxID = Max(PermID), @CurrID = 1
From @Perms;
 
While @CurrID &lt;= @MaxID
  Begin
	Select @PermState = PermState,
		@PermName = PermName,
		@Class = Class,
		@LoginName = LoginName,
		@MajorID = MajorID,
		@SQL = PermState + space(1) + PermName + SPACE(1) +
			Case Class When 101 Then 'On Login::' + QUOTENAME(SubLoginName)
					When 105 Then 'On ' + ClassDesc + '::' + QUOTENAME(SubEndPointName)
					Else '' End +
			' To ' + QUOTENAME(LoginName) + ';'
	From @Perms
	Where PermID = @CurrID;
 
	If Not Exists (Select 1 From sys.server_principals P
				Inner Join sys.server_permissions SP On SP.grantee_principal_id = P.principal_id
				Where SP.state_desc = @PermState
				And SP.permission_name = @PermName
				And SP.class = @Class
				And P.name = @LoginName
				And SP.major_id = @MajorID)
	  Begin
		If @Debug = 0
		  Begin
			Begin Try
				Exec sp_executesql @SQL;
			End Try
			Begin Catch
				Set @ErrNumber = ERROR_NUMBER();
				Set @ErrSeverity = ERROR_SEVERITY();
				Set @ErrState = ERROR_STATE();
				Set @ErrProcedure = ERROR_PROCEDURE();
				Set @ErrLine = ERROR_LINE();
				Set @ErrMsg = ERROR_MESSAGE();
				RaisError(@ErrMsg, 1, 1);
			End Catch
		  End
		Else
		  Begin
			Print @SQL;
		  End
	  End
 
	Set @CurrID = @CurrID + 1;
  End
 
Set NoCount Off;

Ich werde das Skript in Zukunft öfter nutzen, da es für mich und meinem Zwecke der Login Migration sehr gut funktioniert hat.
Vielen Dank an den SQLSoldier

Björn arbeitet in Hamburg als Datenbank-Administrator und Head of Competence für MS SQL und mySQL. Er nimmt regelmäßig an den PASS Regionalgruppen Treffen in Hamburg, den Veranstaltungen der PASS wie SQLSaturday und SQLGrillen teil und er organisiert in Hamburg das Azure Meetup. Er interessiert sich neben den Themen rund um den SQL Server, Powershell und Azure für Science-Fiction, Snowboarden, Backen 😉 und Radfahren.

Extended Support von MS SQL Server 2005 endet im April 2016

Immer noch mit SQL Server 2005? Jetzt ist die Zeit für ein Upgrade!

Können Sie es glauben, es ist schon 10 Jahre her, dass der große SQL Server 2005 veröffentlicht wurde? Der Extended Support für den SQL Server 2005 wird am 12. April 2016 enden. Sie müssen bereits jetzt beginnen eine entsprechende Migration zu planen, damit Sie auch frühzeitig auf eine aktuelle Version von SQL Server migriert haben. Nur durch eine rechtzeitige Migration bzw ein Upgrade können Sie sicherstellen, dass Sie auch nach dem 16.April 2016 noch den Microsoft-Support in Anspruch nehmen können. 

Präsentation des SQL Server 2005 64Bit auf HP Hardware - Tech.Ed SEA 2006 - HP

Aber warum mit der Migration auf einen späteren Zeitpunkt warten, wo möglich dann den Termin zu verpassen, wenn Sie bereits jetzt die Möglichkeit haben neue Werte für Ihr Unternehmen bereitzustellen, wenn Sie rechtzeitig auf eine moderne Datenplattform migrieren?
Viele SQL Server Anwender erleben bereits jetzt die Vorteile einer Aktualisierung auf SQL Server 2014. Zum Beispiel GE Healthcare wollte seinen Kunden eine flexible, skalierbare Plattform bieten, auf der die Anwendungen des Gesundheitswesen weltweit bereitgestellt werden können. Sie erreichten dieses ehrgeizige Ziel mit einer plattform-übergreifenden Cloud-Strategie mit SQL Server 2014 und Microsoft Azure. So erreicht GE Healthcare mehr Kundentreue, mehr Komfort und Service sowie eine verbesserte Verfügbarkeit für seine Kunden.

Planen Sie möglichst zeitnah eine Migration, je früher desto mehr Zeit haben Sie für entsprechende Anpassungsarbeiten oder das Austesten von Möglichkeiten, von denen es zahlreiche Varianten gibt.

  • Soll es erst einmal ein Zwischenstep gemacht werden auf SQL Server 2008 R2, um dann in einem späteren Upgrade der Applikation auch dort den Support zu erhalten.
  • Soll man gleich auch SQL Server 2014 gehen und das “Risiko” eingehen, dass der Applikationshersteller dies vielleicht gar nicht supportet, man aber nicht noch mehr Kosten produzieren will für eine doppelte Migration.
  • Kann man vielleicht sogar Applikationen abschalten, so dass man den SQL Server 2005 gar nicht mehr upgraden oder migrieren muss?
  • Kann man SQL Server konsolidieren und so Migrations-Kosten sparen?
  • Welche Technologien möchte man auf dem neuen SQL Server vielleicht nutzen? In-Memory, dann lieber gleich SQL Server 2014.
  • Welche Ausfall-Szenarien werden im Unternehmen benötigt, damit unternehmens-kritische Anwendungen nicht ausfallen?
  • Will man im Unternehmen vielleicht sogar die Anzahl der (physikalischen) Server reduzieren, mehr auf Cloud-Technologie (zum Beispiel Azure) setzen?

Sie sehen, ich habe hier nur eine geringe Anzahl an Möglichkeiten aufgelistet, aber schon in diesen steckt Potential für wochenlange Projekte mit offenem Ausgang. Beginnen Sie also rechtzeitig mit Migrationsplanung um vor dem Ablauf des Extended Supports für den SQL Server 2005 mit allen notwendigen Planungen und Realisierungen durch zu sein.

Notfalls kann man mit solchen Vorplanungen und entsprechenden Ergebnissen ein passendes Budget für die letzten 3,5 Monate in 2016 einplanen, um auf den “letzten Drücker” eben diese Umsetzung einer Migrationsplanung durchzuführen.

Lesen Sie mehr über SQL Server 2005 Ende der Unterstützung auf der offiziellen Microsoft-Blog und planen Sie Ihre Upgrade heute.

Vielleicht haben Sie ja sogar noch mehr Druck, denn aus eigener Erfahrung weiß ich, dass eine Vielzahl von SQL Server 2005 Instanzen auf einem Windows Server 2003 laufen, für den läuft der Support sogar schon diesen Sommer aus… hier wird es dann besonders dringend.

Verfügbare Produkte Lifecycle-Startdatum Ablaufdatum für Mainstream Support Ablaufdatum für Extended Support Ablaufdatum für Service Pack-Support
Microsoft SQL Server 2005 Compact Edition 19.02.2007 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Developer Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Enterprise Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Enterprise Edition for Itanium Based Systems 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Enterprise X64 Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Express Edition 01.06.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Express Edition with Advanced Services 16.07.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Service Pack 1 18.04.2006 Nicht zutreffend Nicht zutreffend 08.04.2008
Microsoft SQL Server 2005 Service Pack 2 19.02.2007 Nicht zutreffend Nicht zutreffend 12.01.2010
Microsoft SQL Server 2005 Service Pack 3 15.12.2008 Nicht zutreffend Nicht zutreffend 10.01.2012
Microsoft SQL Server 2005 Service Pack 4 13.12.2010 Review-Hinweis Review-Hinweis Microsoft bietet 12 Monate Support nach dem Erscheinen des nachfolgenden Service Packs oder bis zum Ende des Support-Zeitraums für das jeweilige Produkt an, je nachdem welches zuerst eintritt. Besuchen Sie die Lifecycle-Seite, um detaillierte Informationen zu den verschiedenen Microsoft-Produkten zu finden.
Microsoft SQL Server 2005 Standard Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Standard Edition for Itanium Based Systems 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Standard X64 Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Microsoft SQL Server 2005 Workgroup Edition 14.01.2006 12.04.2011 12.04.2016 10.07.2007
Danke an Jason Ong Präsentation des SQL Server 2005 64Bit auf HP Hardware - Tech.Ed SEA 2006 - HP
Björn arbeitet in Hamburg als Datenbank-Administrator und Head of Competence für MS SQL und mySQL. Er nimmt regelmäßig an den PASS Regionalgruppen Treffen in Hamburg, den Veranstaltungen der PASS wie SQLSaturday und SQLGrillen teil und er organisiert in Hamburg das Azure Meetup. Er interessiert sich neben den Themen rund um den SQL Server, Powershell und Azure für Science-Fiction, Snowboarden, Backen 😉 und Radfahren.