<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog de Dje</title>
	<atom:link href="https://blog.developpez.com/dje/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/dje</link>
	<description></description>
	<lastBuildDate>Thu, 31 May 2012 20:33:57 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Applications don&#8217;t know instances</title>
		<link>https://blog.developpez.com/dje/p11059/ms-sql-server/applications_don_t_know_instances</link>
		<comments>https://blog.developpez.com/dje/p11059/ms-sql-server/applications_don_t_know_instances#comments</comments>
		<pubDate>Thu, 31 May 2012 20:33:57 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Les applications ont elles besoin de connaitre le nom de l&#8217;instance sur laquelle leur base(s) de données tourne(nt) ? La majorité du temps&#8230; Non! Elles se connectent sur un serveur et un port, retourné la plupart du temps par le Browser SQL Server dans le cas d&#8217;une instance nommée. Il n&#8217;est pas rare de voir l&#8217;utilisation de CNames pour référencer un serveur spécifique pour une application. Un nom logique pour gagner la flexibilité de changer [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Les applications ont elles besoin de connaitre le nom de l&rsquo;instance sur laquelle leur base(s) de données tourne(nt) ?</p>
<p><span id="more-11"></span></p>
<p>La majorité du temps&#8230; Non! Elles se connectent sur un serveur et un port, retourné la plupart du temps par le Browser SQL Server dans le cas d&rsquo;une instance nommée.<br />
Il n&rsquo;est pas rare de voir l&rsquo;utilisation de CNames pour référencer un serveur spécifique pour une application. Un nom logique pour gagner la flexibilité de changer de serveur facilement en déplacant le pointeur du CName.<br />
C&rsquo;est bien mais&#8230; On traine malheureusement toujours le nom de l&rsquo;instance ou le port de l&rsquo;instance comme un boulet dans la configuration de l&rsquo;application.</p>
<p>Reformulons maintenant ceci:</p>
<blockquote><p>Elles se connectent sur un serveur et un port, retourné la plupart du temps par le Browser SQL Server dans le cas d&rsquo;une instance nommée.</p></blockquote>
<p>comme ceci:</p>
<blockquote><p>Elles se connectent sur une combinaison adresse IP/Port (un socket), par défaut sur le port 1433, ou questionnent le browser pour connaitre le port de l&rsquo;instance si 1433 ne répond pas ou si l&rsquo;on a une instance nommée.</p></blockquote>
<p>Cette reformulation prend du sens si l&rsquo;on considère qu&rsquo;un serveur peut répondre à 1 ou N adresses IP et qu&rsquo;une instance SQL peut être configurée pour écouter sur une ou plusieures adresses IP/Port également.<br />
Voici donc comment se débarrasser du nom de l&rsquo;instance dans les chaines de connection des applications en quelques étapes:<br />
&#8211; Demandez, par instance SQL Serveur, une IP dédiée (Voyez avec votre admin network!)<br />
&#8211; Ajoutez l&rsquo;IP dédiée à votre instance SQL aux propriétés IP de la carte réseau de votre serveur. (Control Panel -> Network and Internet -> Network and Sharing Center -> Local Area Connection -> Properties -> Internet Protocol Version 4 (TCP/IPv4) -> Properties -> Advanced -> Add)<br />
<img src="http://blog.developpez.com/media/serverip.jpg" width="314" height="425" alt="Server IP configuration" /><br />
&#8211; Configurer les propriétés TCP/IP de votre instance SQL via SQL Server Configuration Manager:<br />
Listen All -> No<br />
IP 1: Active Yes, Enabled Yes, IP address &#8211; l&rsquo;adresse IP dédiée pour votre instance, TCP Dynamic Port Rien, TCP Port 1433<br />
<img src="http://blog.developpez.com/media/sql_ip1.jpg" width="452" height="299" alt="Listen All - no" /><br />
<img src="http://blog.developpez.com/media/sql_ip2.jpg" width="452" height="299" alt="SQL Server IP Config" /><br />
&#8211; Créez un a-record pointant vers votre adresse IP dédiée.<br />
&#8211; Utilisz ce a-record dans vos applications pour vous connecter à votre instance.</p>
<p>Voila, le tour est joué.<br />
Si vous souhaitez déplacer une base de données d&rsquo;une instance à une autre pour une application en particulier (i.e: server1\instance1 vers server2\instance2), changez uniquement la reférence du a-record pour pointer vers l&rsquo;IP de la nouvelle instance, plus besoin de modifier le nom de l&rsquo;instance ou le port de celle-ci dans la connection string de votre application.<br />
C&rsquo;est un peu comme créer de simuler des instances par défaut avec des instances nommées.</p>
<p>D&rsquo;un point de vue administration, vous pouvez toujours avoir des instances nommées et continuer comme avant <img src="https://blog.developpez.com/dje/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CMS &#8211; Autoriser l&#8217;ajout de l&#8217;instance du CMS comme serveur enregistré</title>
		<link>https://blog.developpez.com/dje/p10683/ms-sql-server/sql_server_cms_autoriser_l_ajout_de_l_in</link>
		<comments>https://blog.developpez.com/dje/p10683/ms-sql-server/sql_server_cms_autoriser_l_ajout_de_l_in#comments</comments>
		<pubDate>Mon, 30 Jan 2012 18:30:44 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[De base, il n&#8217;est pas possible d&#8217;enregistrer l&#8217;instance même du CMS enregistré. Cependant il existe un moyen de contourner cette limitation&#8230; Outre le fait d&#8217;utiliser un alias DNS ou un trick du genre référencer le nom du serveur par 127.0.0.1, il est possible de contourner cette limitation. Il suffit de modifier la stored procedure [msdb].[dbo].[sp_sysmanagement_add_shared_registered_server] comme ceci: USE [msdb] GO /****** Object: &#160;StoredProcedure [dbo].[sp_sysmanagement_add_shared_registered_server] &#160; &#160;Script Date: 1/30/2012 7:18:04 PM ******/ SET ANSI_NULLS ON GO [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>De base, il n&rsquo;est pas possible d&rsquo;enregistrer l&rsquo;instance même du CMS enregistré.<br />
Cependant il existe un moyen de contourner cette limitation&#8230;</p>
<p><span id="more-1"></span></p>
<p>Outre le fait d&rsquo;utiliser un alias DNS ou un trick du genre référencer le nom du serveur par 127.0.0.1, il est possible de contourner cette limitation.</p>
<p>Il suffit de modifier la stored procedure [msdb].[dbo].[sp_sysmanagement_add_shared_registered_server] comme ceci:</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE [msdb] <br />
GO <br />
/****** Object: &nbsp;StoredProcedure [dbo].[sp_sysmanagement_add_shared_registered_server] &nbsp; &nbsp;Script Date: 1/30/2012 7:18:04 PM ******/ <br />
SET ANSI_NULLS ON <br />
GO <br />
SET QUOTED_IDENTIFIER ON <br />
GO <br />
ALTER PROCEDURE [dbo].[sp_sysmanagement_add_shared_registered_server] <br />
&nbsp; &nbsp; @name sysname, <br />
&nbsp; &nbsp; @server_group_id INT, <br />
&nbsp; &nbsp; @server_name sysname, <br />
&nbsp; &nbsp; @description NVARCHAR(2048) = N'', <br />
&nbsp; &nbsp; @server_type INT, <br />
&nbsp; &nbsp; @server_id INT OUTPUT <br />
AS <br />
BEGIN <br />
&nbsp; &nbsp; DECLARE @retval INT <br />
&nbsp;<br />
&nbsp; &nbsp; EXECUTE @retval = sp_sysmanagement_verify_shared_server_type @server_type <br />
&nbsp;<br />
&nbsp; &nbsp; IF (@retval &lt;&gt; 0) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN(1) -- Failure <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; IF( (@server_group_id IS NULL) OR &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; (@server_group_id NOT IN (SELECT sg.server_group_id FROM msdb.dbo.sysmanagement_shared_server_groups_internal sg))) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35001, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN (1) <br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; IF EXISTS (SELECT * FROM [msdb].[dbo].[sysmanagement_shared_server_groups_internal] &nbsp;sg &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE @server_group_id = sg.server_group_id AND @server_type &lt;&gt; sg.server_type) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35002, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN (1) <br />
&nbsp; &nbsp; END &nbsp; &nbsp; <br />
&nbsp;<br />
&nbsp; &nbsp; IF (@server_name IS NULL) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR(14618, -1, 1, '@server_name') <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN(1) &nbsp; &nbsp;<br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; set @server_name = LTRIM(@server_name) <br />
&nbsp; &nbsp; set @server_name = RTRIM(@server_name) <br />
&nbsp;<br />
&nbsp; &nbsp; -- Disallow relative names <br />
&nbsp; &nbsp; IF ('.' = @server_name) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (1 = CHARINDEX(N'.\', @server_name)) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (1 = CHARINDEX(N'LOCALHOST\', UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS))) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS) = 'LOCALHOST') OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS) = '(LOCAL)') <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35011, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN (1) <br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; -- Autorize to register the CMS instance <br />
&nbsp; &nbsp; --IF (UPPER(@@SERVERNAME collate SQL_Latin1_General_CP1_CS_AS) = UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS)) <br />
&nbsp; &nbsp; --BEGIN <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RAISERROR (35012, -1, -1) <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RETURN (1) <br />
&nbsp; &nbsp; --END <br />
&nbsp;<br />
&nbsp; &nbsp; INSERT INTO [msdb].[dbo].[sysmanagement_shared_registered_servers_internal] <br />
&nbsp; &nbsp; &nbsp; &nbsp; (server_group_id, name, server_name, description, server_type) <br />
&nbsp; &nbsp; VALUES <br />
&nbsp; &nbsp; &nbsp; &nbsp; (@server_group_id, @name, @server_name, @description, @server_type) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; SELECT @server_id = SCOPE_IDENTITY() <br />
&nbsp; &nbsp; RETURN (0) <br />
END</div></div>
</blockquote>
<p>Vous remarquerez que le bout de code suivant a été commenté:</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; -- Autorize to register the CMS instance <br />
&nbsp; &nbsp; --IF (UPPER(@@SERVERNAME collate SQL_Latin1_General_CP1_CS_AS) = UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS)) <br />
&nbsp; &nbsp; --BEGIN <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RAISERROR (35012, -1, -1) <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RETURN (1) <br />
&nbsp; &nbsp; --END</div></div>
</blockquote>
<p>Je ne garanti en aucun cas les potentiels effets de bord pouvant survenir.<br />
Encore une fois la règle est de tester!</p>
<p>Si vous optez pour cette solution, pensez aussi à mettre à jour la procédure suivante, celle d&rsquo;update d&rsquo;un serveur avec le code ci-dessous:</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE [msdb] <br />
GO <br />
/****** Object: &nbsp;StoredProcedure [dbo].[sp_sysmanagement_update_shared_registered_server] &nbsp; &nbsp;Script Date: 1/31/2012 9:02:06 PM ******/ <br />
SET ANSI_NULLS ON <br />
GO <br />
SET QUOTED_IDENTIFIER ON <br />
GO <br />
ALTER PROCEDURE [dbo].[sp_sysmanagement_update_shared_registered_server] <br />
&nbsp; &nbsp; @server_id INT, <br />
&nbsp; &nbsp; @server_name sysname = NULL, <br />
&nbsp; &nbsp; @description NVARCHAR(2048) = NULL <br />
AS <br />
BEGIN <br />
&nbsp; &nbsp; IF (@server_id IS NULL) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35006, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN(1) <br />
&nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; IF NOT EXISTS (SELECT * FROM [msdb].[dbo].[sysmanagement_shared_registered_servers_internal] WHERE server_id = @server_id) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35007, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN(1) <br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; IF (@server_name IS NULL) <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; SET @server_name = (select server_name FROM [msdb].[dbo].[sysmanagement_shared_registered_servers_internal] WHERE server_id = @server_id) <br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; set @server_name = LTRIM(@server_name) <br />
&nbsp; &nbsp; set @server_name = RTRIM(@server_name) <br />
&nbsp;<br />
&nbsp; &nbsp; -- Disallow relative names <br />
&nbsp; &nbsp; IF ('.' = @server_name) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (1 = CHARINDEX(N'.\', @server_name)) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (1 = CHARINDEX(N'LOCALHOST\', UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS))) OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS) = 'LOCALHOST') OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; (UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS) = '(LOCAL)') <br />
&nbsp; &nbsp; BEGIN <br />
&nbsp; &nbsp; &nbsp; &nbsp; RAISERROR (35011, -1, -1) <br />
&nbsp; &nbsp; &nbsp; &nbsp; RETURN (1) <br />
&nbsp; &nbsp; END <br />
&nbsp;<br />
&nbsp; &nbsp; --IF (UPPER(@@SERVERNAME collate SQL_Latin1_General_CP1_CS_AS) = UPPER(@server_name collate SQL_Latin1_General_CP1_CS_AS)) <br />
&nbsp; &nbsp; --BEGIN <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RAISERROR (35012, -1, -1) <br />
&nbsp; &nbsp; -- &nbsp; &nbsp;RETURN (1) <br />
&nbsp; &nbsp; --END <br />
&nbsp;<br />
&nbsp; &nbsp; UPDATE [msdb].[dbo].[sysmanagement_shared_registered_servers_internal] <br />
&nbsp; &nbsp; &nbsp; &nbsp; SET server_name = ISNULL(@server_name, server_name), <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description = ISNULL(@description, description) <br />
&nbsp; &nbsp; WHERE <br />
&nbsp; &nbsp; &nbsp; &nbsp; server_id = @server_id <br />
&nbsp; &nbsp; RETURN (0) <br />
END</div></div>
</blockquote>
<p>Bon hack,<br />
Dje</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell &#8211; Central Management Server export &#8211; import</title>
		<link>https://blog.developpez.com/dje/p10680/ms-sql-server/powershell_central_management_server_exp_2</link>
		<comments>https://blog.developpez.com/dje/p10680/ms-sql-server/powershell_central_management_server_exp_2#comments</comments>
		<pubDate>Sat, 28 Jan 2012 21:44:26 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Mikedavem propose une solution pour exporter la liste des serveurs et groupes contenus dans un CMS. Trouvant la méthode assez compliquée par rapport à ce qu&#8217;il est réalisable au niveau du GUI, je me suis posé la question &#171;&#160;Comment automatiser ce que le GUI fait ?&#160;&#187;. Premier reflexe: SQL Profiler&#8230; Caramba! On ne voit rien passer. Second reflexe (toujours moins naturel celui-la): Powershell ! Pre-requis: La session powershell doit être ouverte sur le serveur ou [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Mikedavem propose <a href="http://blog.developpez.com/mikedavem/p10675/sql-server-2008/migrer-la-configuration-darsquo-un-serve/#more10675">une solution pour exporter la liste des serveurs et groupes contenus dans un CMS</a>.</p>
<p>Trouvant la méthode assez compliquée par rapport à ce qu&rsquo;il est réalisable au niveau du GUI, je me suis posé la question &laquo;&nbsp;Comment automatiser ce que le GUI fait ?&nbsp;&raquo;.</p>
<p>Premier reflexe: SQL Profiler&#8230; Caramba! On ne voit rien passer.</p>
<p>Second reflexe (toujours moins naturel celui-la): Powershell !<br />
<span id="more-15"></span><br />
Pre-requis:<br />
La session powershell doit être ouverte sur le serveur ou le CMS tourne &#8211; ou en utilisant du remote powershell (pas teste).<br />
Le snappin/module (2008/2012) sqlps doit être chargé.</p>
<p>En regardant un peu la documentation, on peut remarquer que sqlps, au travers du provider SqlServer, permet de naviguer au travers des serveurs enregistrés.</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#Liste des providers <br />
Get-PSProvider <br />
#Liste des &quot;folders&quot; du provider SQLSERVER <br />
set-location SQLSERVER: <br />
ls</div></div>
</blockquote>
<p><img src="http://blog.developpez.com/media/provider.png" width="713" height="424" alt="Provider_SQLServer" /></p>
<p>Pour naviguer on fera comme pour naviguer dans une arborescence de file system:</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd .\SQLRegistration #Serveurs enregistrés <br />
cd '.\Central Management Server Group' #CMS (cd pouvez taper cd &lt;tab&gt; et powershell completera la ligne pour vous) <br />
cd .\%2E%5CSQL11 #le nom de mon CMS qui est literalement .\SQL11 - Vive le trick ci-dessus (cd &lt;tab&gt;) pour retrouver le bon nom ;) <br />
ls #presente la liste de serveurs/groupes presents à la racine du CMS</div></div>
</blockquote>
<p><img src="http://blog.developpez.com/media/CMS_location.png" width="780" height="198" alt="CMSLocation" /></p>
<p>Maintenant regardons les méthodes existantes pour l&rsquo;objet dans lequel nous nous trouvons ainsi que de quelle classe est cet objet (si vous débutez avec le powershell et que ceci vous semble bizarre&#8230; C&rsquo;est normal &#8230; Ou pas&#8230; En tout cas c&rsquo;est l&rsquo;effet que ca m&rsquo;a fait ^^):</p>
<blockquote><p>Get-Item . | Get-Member</p></blockquote>
<p>On peut voir que le nom de la classe (TypeName) de l&rsquo;objet est <a href="http://msdn.microsoft.com/fr-fr/library/microsoft.sqlserver.management.registeredservers.servergroup(v=sql.110).aspx">Microsoft.SqlServer.Management.RegisteredServers.ServerGroup</a> et <a href="http://msdn.microsoft.com/fr-fr/library/microsoft.sqlserver.management.registeredservers.servergroup.export(v=sql.110).aspx">une méthode appelée export!</a></p>
<p><img src="http://blog.developpez.com/media/CMS_methods.png" width="964" height="664" alt="CMS_Methods" /></p>
<p>C&rsquo;est cette methode qui va nous servir à réaliser l&rsquo;export.</p>
<p>Voici le script permettant de réaliser cet export (n&rsquo;oubliez pas les pré-requis! et pensez à changer les valeurs des variables ;)):</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$CMSPath = 'SQLSERVER:\SQLRegistration\Central Management Server Group\%2E%5CSQL11' #Location of the Central Management server to be exported <br />
$exportFile = 'C:\Powershell\CMS\cms.xml' #Path of the export file <br />
&nbsp;<br />
set-location $CMSPath <br />
(get-item .).export($exportFile, 'None')</div></div>
</blockquote>
<p>Maintenant, pour l&rsquo;import, même principe en utilisant cette fois ci la méthode&#8230; <a href="http://msdn.microsoft.com/fr-fr/library/microsoft.sqlserver.management.registeredservers.servergroup.import(v=sql.110).aspx">import</a> &#8230; Je suis sur que vous l&rsquo;aviez déjà deviné ;):</p>
<blockquote>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$CMSPath = 'SQLSERVER:\SQLRegistration\Central Management Server Group\%2E%5CSQL11' #Location of the Central Management server where to import <br />
$importFile = 'C:\Powershell\CMS\cms.xml' #Path of the file to import <br />
&nbsp;<br />
set-location $CMSPath <br />
(get-item .).import($importFile)</div></div>
</blockquote>
<p>Voila !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exécuter un package SSIS en utilisant un proxy</title>
		<link>https://blog.developpez.com/dje/p10545/ms-sql-server/executer_un_package_ssis_en_utilisant_un</link>
		<comments>https://blog.developpez.com/dje/p10545/ms-sql-server/executer_un_package_ssis_en_utilisant_un#comments</comments>
		<pubDate>Sun, 27 Nov 2011 22:00:07 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici les différentes étapes nécessaires pour exécuter un package SSIS au travers de l&#8217;agent de SQL Server en utilisant les crédentials d&#8217;un utilisateur particulier au travers d&#8217;un proxy: La première étape consiste à créer un credential au niveau de l&#8217;onglet de sécurité de votre instance SQL Serveur: Connectez-vous à votre instance Déployez l&#8217;onglet security Clic droit sur credential -> new credential Complétez les différentes informations: Le crédential name sera le nom de votre crédential &#8211; [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici les différentes étapes nécessaires pour exécuter un package SSIS au travers de l&rsquo;agent de SQL Server en utilisant les crédentials d&rsquo;un utilisateur particulier au travers d&rsquo;un proxy:<br />
<span id="more-9"></span><br />
La première étape consiste à créer un credential au niveau de l&rsquo;onglet de sécurité de votre instance SQL Serveur:<br />
Connectez-vous à votre instance<br />
Déployez l&rsquo;onglet security<br />
Clic droit sur credential -> new credential<br />
<img src="http://blog.developpez.com/media/credential_new.png" width="288" height="244" alt="Nouveau credential" /></p>
<p>Complétez les différentes informations:<br />
Le crédential name sera le nom de votre crédential &#8211; Vous pouvez ici définir ce que vous voulez<br />
Le champ identiy correspond au compte que vous souhaitez utiliser au format (domaine\username)<br />
Le mot de passe correspond au mot de passe du compte défini au niveau du champ identity<br />
Cliquez ensuite sur OK<br />
<img src="http://blog.developpez.com/media/credential_new_1.png" width="700" height="624" alt="proxy creation" /></p>
<p>Voici votre nouveau credential de créé:<br />
<img src="http://blog.developpez.com/media/credential_created.png" width="290" height="279" alt="Credential created" /></p>
<p>Maintenant que vous avez un credential tout frais prêt à être utilisé, déployez l&rsquo;agent SQL Serveur et faites un clic droit sur Proxies -> new proxy:<br />
<img src="http://blog.developpez.com/media/proxy.png" width="289" height="389" alt="New proxy" /></p>
<p>Complétez le formulaire de la manière suivante:<br />
Proxy name sera le nom de votre proxy &#8211; Vous pouvez ici définir ce que vous voulez<br />
Crédential name est le nom logique de votre crédential précedemment créé<br />
Cochez la case SQL Server Integration Service Package &#8211; cela spécifie que votre proxy est autorisé à exécuter des pacakages SSIS. Vous pourriez faire de même pour exécuter des commandes OS en cochant Operating System (CmdExec)<br />
Cliquez sur OK<br />
<img src="http://blog.developpez.com/media/proxy_1.png" width="701" height="631" alt="" /></p>
<p>Maintenant que vous avez un proxy créé, mappé sur un credential, il reste à définir au niveau de l&rsquo;étape de votre job SQL Serveur exécutant votre package SSIS que cette étape doit être réalisée en utilisant ce proxy:<br />
Ouvrez votre job<br />
Ouvrez le step de cotre job exécutant le package SSIS<br />
Au niveau du champ &laquo;&nbsp;Run as&nbsp;&raquo;, sélectionnez votre proxy<br />
Cliquez OK<br />
<img src="http://blog.developpez.com/media/job_step.png" width="701" height="629" alt="job step" /></p>
<p>Et voilà, le tour est joué!</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remonter les informations de capacité des disques avec Powershell</title>
		<link>https://blog.developpez.com/dje/p10587/ms-sql-server/remonter_les_informations_de_capacite_de_1</link>
		<comments>https://blog.developpez.com/dje/p10587/ms-sql-server/remonter_les_informations_de_capacite_de_1#comments</comments>
		<pubDate>Wed, 14 Dec 2011 20:40:24 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un petit script permettant de lister l&#8217;ensemble des volumes d&#8217;un serveur et des différents mount points: foreach($volume IN gwmi -Class win32_volume) &#160; { &#160; &#160; $Capacity = $volume.capacity/1073741824; &#160; &#160; &#160; $freeSpace= $volume.freespace/1073741824; &#160; &#160; &#160; $used = $Capacity - $freeSpace; &#160; &#160; &#160; write-host $volume.name ' - Capacity:' $Capacity ' - Free space:' $freespace ' - Used:' $used } On peut l&#8217;étendre facilement pour l&#8217;utiliser sur un serveur distant l&#8217;autorisant grace au paramètre [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici un petit script permettant de lister l&rsquo;ensemble des volumes d&rsquo;un serveur et des différents mount points:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">foreach($volume IN gwmi -Class win32_volume) &nbsp;<br />
{ <br />
&nbsp; &nbsp; $Capacity = $volume.capacity/1073741824; &nbsp;<br />
&nbsp; &nbsp; $freeSpace= $volume.freespace/1073741824; &nbsp;<br />
&nbsp; &nbsp; $used = $Capacity - $freeSpace; &nbsp;<br />
&nbsp; &nbsp; write-host $volume.name ' - Capacity:' $Capacity ' - Free space:' $freespace ' - Used:' $used <br />
}</div></div>
<p><span id="more-13"></span><br />
On peut l&rsquo;étendre facilement pour l&rsquo;utiliser sur un serveur distant l&rsquo;autorisant grace au paramètre -ComputerName de l&rsquo;alias gwmi:<br />
(Au passage un peu de cosmétique pour spécifier la mesure des volumes et une petite information intéressante, la taille du block de disque)</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$TargetComputer = &quot;MonServer&quot; <br />
&nbsp;<br />
foreach($volume IN gwmi -ComputerName $TargetComputer -Class win32_volume) &nbsp;<br />
{ <br />
&nbsp; &nbsp; $Capacity = $volume.capacity/1073741824; &nbsp;<br />
&nbsp; &nbsp; $freeSpace= $volume.freespace/1073741824; &nbsp;<br />
&nbsp; &nbsp; $used = $Capacity - $freeSpace; &nbsp;<br />
&nbsp; &nbsp; write-host $volume.name ' - Capacity(GB):' $Capacity ' - Free space(GB):' $freespace ' - Used(GB):' $used ' - Block size(K):' $volume.blocksize <br />
}</div></div>
<p>Allons un peu plus loin et faisons maintenant la meme chose, sur un ensemble de serveurs listés dans un fichier:<br />
Au passage, un petit filtre pour ne prendre que les disques durs locaux.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$monFichierServeur = &quot;c:\powershell\ServerList.txt&quot; <br />
&nbsp;<br />
foreach ($TargetComputer in get-content $monFichierServeur) <br />
{ <br />
&nbsp; foreach($volume IN gwmi -ComputerName $TargetComputer -Class win32_volume) &nbsp;<br />
&nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; if ($volume.DriveType -eq 3) #Filtrons sur les disques durs <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$Capacity = $volume.capacity/1073741824; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$freeSpace= $volume.freespace/1073741824; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$used = $Capacity - $freeSpace; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write-host 'ServerName:' $TargetComputer ' - VolumeName:' &nbsp;$volume.name ' - Capacity(GB):' $Capacity ' - FreeSpace(GB):' $freespace ' - Used(GB):' $used ' - BlockSize(K):' $volume.blocksize <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; } <br />
}</div></div>
<p>Continuons un peu le chemin, ca devient dur de s&rsquo;imaginer lire toute une console du listing des volumes de tous nos serveurs:<br />
Ajoutons un fichier de sortie nommer comme avec le nom du serveur au format .csv:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$monFichierServeur = &quot;c:\powershell\ServerList.txt&quot; <br />
$OutPath = &nbsp;&quot;c:\powershell\out\&quot; <br />
&nbsp;<br />
foreach ($TargetComputer in get-content $monFichierServeur) <br />
{ <br />
&nbsp; &nbsp; $outFile = $OutPath + $TargetComputer + &quot;.csv&quot; <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &quot;&quot;&quot;ServerName&quot;&quot;;&quot;&quot;VolumeName&quot;&quot;;&quot;&quot;Capacity(GB)&quot;&quot;;&quot;&quot;FreeSpace(GB)&quot;&quot;;&quot;&quot;Used(GB)&quot;&quot;;&quot;&quot;BlockSize(K)&quot;&quot;&quot; | out-file $outFile <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; foreach($volume IN gwmi -ComputerName $TargetComputer -Class win32_volume) &nbsp;<br />
&nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; if ($volume.DriveType -eq 3) #Filtrons sur les disques durs <br />
&nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$Capacity &nbsp; = $volume.capacity/1073741824; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$freeSpace &nbsp;= $volume.freespace/1073741824; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$volumeName = $volume.name &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$blockSize &nbsp;= $volume.blocksize <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$used = $Capacity - $freeSpace; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&quot;&quot;&quot;+$TargetComputer+&quot;&quot;&quot;;&quot;&quot;&quot;+$volumeName+&quot;&quot;&quot;;&quot;&quot;&quot;+$Capacity+&quot;&quot;&quot;;&quot;&quot;&quot;+$freespace+&quot;&quot;&quot;;&quot;&quot;&quot;+$used+&quot;&quot;&quot;;&quot;&quot;&quot;+$blockSize+&quot;&quot;&quot;&quot; | out-file $outFile -append <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; } <br />
}</div></div>
<p>Terminons avec un bout de code a sauvegarder dans un fichier de type .ps1 auquel on peut passer 2 arguments: le nom du fichier de serveur et le path de sortie:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Param <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; [string]$monFichierServeur, <br />
&nbsp; &nbsp; &nbsp; &nbsp; [string]$outPath <br />
&nbsp; &nbsp; ) <br />
&nbsp;<br />
function get-volumes <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; [string]$monFichierServeur, <br />
&nbsp; &nbsp; &nbsp; &nbsp; [string]$outPath <br />
&nbsp; &nbsp; ) <br />
&nbsp; &nbsp; &nbsp;<br />
{ <br />
&nbsp; &nbsp; Write-Host $outPath <br />
&nbsp; &nbsp; foreach ($TargetComputer in get-content $monFichierServeur) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; $outFile = $OutPath + &quot;\&quot; + $TargetComputer + &quot;.csv&quot; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;&quot;ServerName&quot;&quot;;&quot;&quot;VolumeName&quot;&quot;;&quot;&quot;Capacity(GB)&quot;&quot;;&quot;&quot;FreeSpace(GB)&quot;&quot;;&quot;&quot;Used(GB)&quot;&quot;;&quot;&quot;BlockSize(K)&quot;&quot;&quot; | out-file $outFile <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; foreach($volume IN gwmi -ComputerName $TargetComputer -Class win32_volume) &nbsp;<br />
&nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($volume.DriveType -eq 3) #Filtrons sur les disques durs <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$Capacity &nbsp; = $volume.capacity/1073741824; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$freeSpace &nbsp;= $volume.freespace/1073741824; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$volumeName = $volume.name &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$blockSize &nbsp;= $volume.blocksize <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$used = $Capacity - $freeSpace; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;&quot;&quot;&quot;+$TargetComputer+&quot;&quot;&quot;;&quot;&quot;&quot;+$volumeName+&quot;&quot;&quot;;&quot;&quot;&quot;+$Capacity+&quot;&quot;&quot;;&quot;&quot;&quot;+$freespace+&quot;&quot;&quot;;&quot;&quot;&quot;+$used+&quot;&quot;&quot;;&quot;&quot;&quot;+$blockSize+&quot;&quot;&quot;&quot; | out-file $outFile -append <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; } <br />
} <br />
&nbsp;<br />
get-volumes $monFichierServeur $outPath</div></div>
<p>Soit le fichier VolumeInfoOutFileParam.ps1, l&rsquo;appel se fait de la manière suivante:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">.\VolumeInfoOutFileParam.ps1 &quot;C:\Powershell\ServerList.txt&quot; &quot;C:\Powershell\Out&quot;</div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powershell &#8211; Invoke-Sqlcmd</title>
		<link>https://blog.developpez.com/dje/p10665/ms-sql-server/powershell_invoke_sqlcmd</link>
		<comments>https://blog.developpez.com/dje/p10665/ms-sql-server/powershell_invoke_sqlcmd#comments</comments>
		<pubDate>Sat, 21 Jan 2012 18:40:32 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le module powershell SQLPS introduit une serie de commandes powershell destinées à l&#8217;interaction avec les composants de la suite SQL Server et ce depuis SQL Server 2008. Ce module permet aussi entre autre de naviguer au travers des objets se trouvant sur les differentes instances SQL Server comme au travers de fichiers en mode console. Cela introduit des possibilités de scripting intéressantes car l&#8217;on peut profiter de la puissance de powershell pour réaliser ces scripts. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le module powershell SQLPS introduit une serie de commandes powershell destinées à l&rsquo;interaction avec les composants de la suite SQL Server et ce depuis SQL Server 2008.<br />
Ce module permet aussi entre autre de naviguer au travers des objets se trouvant sur les differentes instances SQL Server comme au travers de fichiers en mode console.<br />
Cela introduit des possibilités de scripting intéressantes car l&rsquo;on peut profiter de la puissance de powershell pour réaliser ces scripts.<br />
<span id="more-12"></span><br />
La commande Invoke-Sqlcmd, commande qui comme son nom peut déjà vous y avoir fait penser, permet d&rsquo;invoquer des scripts tels qu&rsquo;on pourrait le faire avec l&rsquo;utilitaire Sqlcmd.<br />
Vous pourrez découvrir la description (complète) de cette commande en tapant dans une invite de commande SQLPS (ou Powershell en ayant chargé le module adéquat &#8211; sur un serveur ou Denali a été installé: <strong><code class="codecolorer text default"><span class="text">Import-Module sqlps -DisableNameChecking</span></code></strong>) :<br />
<strong><code class="codecolorer text default"><span class="text">Get-Help Invoke-Sqlcmd</span></code></strong><br />
Pour des exemples rapides:<br />
<strong><code class="codecolorer text default"><span class="text">Get-Help Invoke-Sqlcmd -Examples</span></code></strong><br />
Ou pour la documentation exhaustive:<br />
<strong><code class="codecolorer text default"><span class="text">Get-Help Invoke-Sqlcmd -Full</span></code></strong></p>
<p>Que faire avec cela ?</p>
<p>Voici 2 exemples:</p>
<p><em>Exporter le résultat d&rsquo;une query dans un fichier csv:</em></p>
<p><strong><code class="codecolorer text default"><span class="text">Invoke-Sqlcmd -ServerInstance &quot;WIN-QDRSKD4G3GP\SQL11&quot; -Database Volume -Query &quot;select * from volumetest&quot; | export-csv &quot;c:\temp\extract_ps.csv&quot;</span></code></strong><br />
Ce que j&rsquo;apprécie grandement, c&rsquo;est la simplicité d&rsquo;écriture.<br />
Ce bout de code peut être placé tel quel dans le step d&rsquo;un job de l&rsquo;agent SQL Server (de type PowerShell) et être exécuté sans problème.<br />
<img src="http://blog.developpez.com/media/invoke_sqlcmd_job.png" width="859" height="496" alt="Job" /></p>
<p>Ci-dessous un extrait du fichier généré:</p>
<blockquote><p>#TYPE System.Data.DataRow<br />
&laquo;&nbsp;id&nbsp;&raquo;,&nbsp;&raquo;UniqueID&nbsp;&raquo;<br />
&laquo;&nbsp;1&nbsp;&raquo;,&nbsp;&raquo;9ea1edd1-0163-43c8-a12c-036329425f3f&nbsp;&raquo;<br />
&laquo;&nbsp;2&nbsp;&raquo;,&nbsp;&raquo;1b30db32-bf16-4eb6-9cb5-52abfde676d9&Prime;<br />
&laquo;&nbsp;3&nbsp;&raquo;,&nbsp;&raquo;cb568ce5-a853-48f2-95a5-63b84da0e137&Prime;</p></blockquote>
<p>Vous remarquerez la première ligne, mentionnant le type de l&rsquo;objet ayant ete exporté. Cela provient de la fonction export-xml qui permet de typer les objets exportés permettant par la suite de les réimporter tout en conservant les propriétés de l&rsquo;objet source.<br />
La seconde étant le nom des colonnes de la table exportée.<br />
Et ensuite les différentes lignes exportées au format .csv.</p>
<p>Coté performances par contre il ne faut pas être pressé malheureusement!!! <img src="https://blog.developpez.com/dje/wp-includes/images/smilies/icon_sad.gif" alt=":(" class="wp-smiley" /><br />
Rien à voir avec BCP!<br />
Voici la comparaison de vitesse pour une extraction via BCP et utilisant Invoke-Sqlcmd pour un volume de plus ou moins 150Mo:<br />
<img src="http://blog.developpez.com/media/invoke_sqlcmd_vs_bcp.png" width="580" height="44" alt="" /></p>
<p>On ne l&rsquo;utilisera donc pas pour des exports massifs au quotidien si l&rsquo;on souhaite de la vitesse.<br />
Par contre pour un export one shot vite fait, si la volumétrie n&rsquo;est pas trop importante, pourquoi pas!<br />
Passons à l&rsquo;exemple suivant..</p>
<p><em>Utiliser la commande dans un script:</em></p>
<p>Dans les billets précédents, je regardais comment extraire les informations des volumes de serveurs en se servant du powershell et de WMI.<br />
Je me suis posé la question &#8211; et si la liste de serveurs provenait d&rsquo;une table ?<br />
Et voici la réponse:<br />
<strong></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Get-WmiObject win32_volume -Filter &quot;drivetype=3&quot; -computername (Invoke-Sqlcmd -ServerInstance .\SQL11 -Query &quot;select name from volume.dbo.servername&quot; | foreach {$_.name}) ` <br />
| Add-Member -MemberType ScriptProperty -Name FreeSpaceinGB -Value {[math]::Round(($this.freespace / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name UsedSpaceinGB -Value {[math]::Round((($this.capacity - $this.freespace) / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name SizeinGB -Value {[math]::Round(($this.capacity / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name FreespacePercent -Value {[math]::Round(([int64]$this.freespace / [int64]$this.capacity * 100),2)} -PassThru ` <br />
| select __SERVER, Name, FreespaceinGB, UsedSpaceinGB, SizeinGB, FreespacePercent, BlockSize ` <br />
| export-csv &quot;C:\Powershell\Disks\list.csv&quot;</div></div>
<p></strong></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remonter les informations de capacité des disques avec Powershell (partie 2)</title>
		<link>https://blog.developpez.com/dje/p10628/ms-sql-server/remonter_les_informations_de_capacite_de_2</link>
		<comments>https://blog.developpez.com/dje/p10628/ms-sql-server/remonter_les_informations_de_capacite_de_2#comments</comments>
		<pubDate>Tue, 03 Jan 2012 19:21:41 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Powershell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Suite à l&#8217;article précédent, j&#8217;ai continué mes recherches, spécialement pour pouvoir bénéficier de la commande export-csv&#8230; Au passage, ajout de propriétés calculées et chargement direct du fichier d&#8217;input, ce qui permet d&#8217;écrire le script en une seule ligne (je l&#8217;ai splitée par question de lisibilité&#8230;): #CSV format based on server list file Get-WmiObject win32_volume -Filter &#34;drivetype=3&#34; -computername @(get-content &#34;C:\Powershell\Disks\ServerList.txt&#34;) ` &#124; Add-Member -MemberType ScriptProperty -Name FreeSpaceinGB -Value {[math]::Round(($this.freespace / 1GB),2)} -PassThru ` &#124; Add-Member -MemberType [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Suite à l&rsquo;article précédent, j&rsquo;ai continué mes recherches, spécialement pour pouvoir bénéficier de la commande export-csv&#8230;<br />
Au passage, ajout de propriétés calculées et chargement direct du fichier d&rsquo;input, ce qui permet d&rsquo;écrire le script en une seule ligne (je l&rsquo;ai splitée par question de lisibilité&#8230;):</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#CSV format based on server list file <br />
Get-WmiObject win32_volume -Filter &quot;drivetype=3&quot; -computername @(get-content &quot;C:\Powershell\Disks\ServerList.txt&quot;) ` <br />
| Add-Member -MemberType ScriptProperty -Name FreeSpaceinGB -Value {[math]::Round(($this.freespace / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name UsedSpaceinGB -Value {[math]::Round((($this.capacity - $this.freespace) / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name SizeinGB -Value {[math]::Round(($this.capacity / 1GB),2)} -PassThru ` <br />
| Add-Member -MemberType ScriptProperty -Name FreespacePercent -Value {[math]::Round(([int64]$this.freespace / [int64]$this.capacity * 100),2)} -PassThru ` <br />
| select __SERVER, Name, FreespaceinGB, UsedSpaceinGB, SizeinGB, FreespacePercent, BlockSize ` <br />
| export-csv &quot;C:\Powershell\Disks\list.csv&quot;</div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mythe &#8211; un full backup sans l&#8217;option with_copy only casse une chaine de log backup</title>
		<link>https://blog.developpez.com/dje/p10519/ms-sql-server/mythe_un_full_backup_sans_l_option_with</link>
		<comments>https://blog.developpez.com/dje/p10519/ms-sql-server/mythe_un_full_backup_sans_l_option_with#comments</comments>
		<pubDate>Sat, 19 Nov 2011 00:00:13 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[J'ai longtemps cru qu'un full backup d'une base de données en full recovery model rompait la chaine des transaction logs backup de la base de données. Je pensais qu'il était donc indispensable d'utiliser l'option with copy_only pour effectuer le backup de celle-ci afin de ne pas casser la chaine de tlogs backup. Jusqu'au beau jour ou un collègue me dit que ce n'est pas le cas. - Sérieux ?! Je suis sceptique... La dessus, j&#8217;ouvre [&#8230;]]]></description>
				<content:encoded><![CDATA[<pre>
J'ai longtemps cru qu'un full backup d'une base de données en full recovery model rompait la chaine des transaction logs backup de la base de données. 
Je pensais qu'il était donc indispensable d'utiliser l'option with copy_only pour effectuer le backup de celle-ci afin de ne pas casser la chaine de tlogs backup.
Jusqu'au beau jour ou un collègue me dit que ce n'est pas le cas. 

- Sérieux ?! Je suis sceptique...
</pre>
<p><span id="more-8"></span></p>
<p>La dessus, j&rsquo;ouvre SSMS et j&rsquo;effectue un petit test (le code ci-dessous n&rsquo;est pas l&rsquo;original ;)):</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">create database test <br />
alter database test set recovery full <br />
backup database test to disk = 'c:\temp\test.bak1' <br />
&nbsp;<br />
go <br />
use test <br />
go <br />
&nbsp;<br />
create table testTable <br />
( <br />
&nbsp; id int <br />
) <br />
&nbsp;<br />
backup log test to disk = 'c:\temp\test.trn1' <br />
insert into testTable select 1 <br />
backup database test to disk = 'c:\temp\test.bak2' <br />
insert into testTable select 2 <br />
backup log test to disk = 'c:\temp\test.trn2' <br />
insert into testTable select 3 <br />
backup log test to disk = 'c:\temp\test.trn3_copy' with copy_only <br />
insert into testTable select 4 <br />
backup log test to disk = 'c:\temp\test.trn4' <br />
insert into testTable select 5 <br />
backup log test to disk = 'c:\temp\test.trn5' <br />
insert into testTable select 6 <br />
alter database test set recovery simple <br />
alter database test set recovery full <br />
backup database test to disk = 'c:\temp\test.bak6' <br />
backup log test to disk = 'c:\temp\test.trn6' <br />
&nbsp;<br />
GO <br />
use master <br />
GO <br />
drop database test <br />
GO <br />
&nbsp;<br />
-- Full backup does not break the log chain and tlog backup with no copy neither <br />
print 'Restore session 1' <br />
restore database test from disk = 'c:\temp\test.bak1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn2' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn4' with recovery <br />
select 'Restore session 1', * from test.dbo.testTable <br />
&nbsp;<br />
GO <br />
drop database test <br />
GO <br />
&nbsp;<br />
-- This one is working too <br />
print 'Restore session 2' <br />
restore database test from disk = 'c:\temp\test.bak1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn2' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn3_copy' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn4' with recovery <br />
select 'Restore session 2', * from test.dbo.testTable <br />
&nbsp;<br />
GO <br />
drop database test <br />
GO <br />
&nbsp;<br />
-- Transaction log backup (without only_copy option) missing prevent to rebuild the chain <br />
-- Error: The log in this backup set begins at LSN 21000000017200001, which is too recent to apply to the database. An earlier log backup that includes LSN 21000000017100001 can be restored. <br />
&nbsp;<br />
print 'Restore session 3' <br />
restore database test from disk = 'c:\temp\test.bak1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn2' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn3_copy' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn5' with recovery <br />
select 'Restore session 3', * from test.dbo.testTable <br />
&nbsp;<br />
GO <br />
drop database test <br />
GO <br />
&nbsp;<br />
-- switch to simple recovery model &nbsp;<br />
-- Error: This log cannot be restored because a gap in the log chain was created. Use more recent data backups to bridge the gap. <br />
&nbsp;<br />
print 'Restore session 4' <br />
restore database test from disk = 'c:\temp\test.bak1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn1' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn2' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn4' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn5' with norecovery <br />
restore database test from disk = 'c:\temp\test.trn6' with norecovery <br />
select 'Restore session 4', * from test.dbo.testTable</div></div>
<p>&#8211; Ah ben oui ! Tu as raison. Tu viens de casser un mythe, j&rsquo;y croyais dur comme fer!</p>
<p>Comme on peut le voir ci-dessus, un full backup effectué sans l&rsquo;option with copy_only ne casse pas une chaine de transaction log backup.<br />
On remarquera qu&rsquo;un backup du transaction log avec l&rsquo;option with copy_only non plus.</p>
<p>Par contre, un transaction log backup effectué et manquant (restore session 3 &#8211; le fichier c:\temp\test.trn4) provoque bien une rupture de la chaine.<br />
L&rsquo;erreur générée étant:<br />
Msg 4305, Level 16, State 1, Line 10<br />
The log in this backup set begins at LSN **********************, which is too recent to apply to the database. An earlier log backup that includes LSN **********************, can be restored.<br />
Msg 3013, Level 16, State 1, Line 10<br />
RESTORE DATABASE is terminating abnormally.</p>
<p>On remarquera aussi que le fait de switcher le recovery modele de la base de données en simple puis de le repasser en full rompt également la chaine des transaction logs backup.<br />
L&rsquo;erreur étant maintenant différente:<br />
Msg 4312, Level 16, State 1, Line 11<br />
This log cannot be restored because a gap in the log chain was created. Use more recent data backups to bridge the gap.<br />
Msg 3013, Level 16, State 1, Line 11<br />
RESTORE DATABASE is terminating abnormally.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[SQL Server 2011] Server roles</title>
		<link>https://blog.developpez.com/dje/p9521/ms-sql-server/sql_server_2011_server_roles_1</link>
		<comments>https://blog.developpez.com/dje/p9521/ms-sql-server/sql_server_2011_server_roles_1#comments</comments>
		<pubDate>Sun, 21 Nov 2010 10:15:04 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Creating custom server roles is a new feature coming with the SQL Server 2011 CTP1. It allows to create custom roles on server level to define specific set of permissions on server objects. Great ! What to do with this new feature ? I want to share here 2 exemples I will definitively use: Defining a Sharepoint Service account role which include both security administrator role and dbcreator role: USE [master] GO CREATE SERVER ROLE [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Creating custom server roles is a new feature coming with the SQL Server 2011 CTP1.<br />
It allows to create custom roles on server level to define specific set of permissions on server objects.<br />
Great ! What to do with this new feature ?</p>
<p>I want to share here 2 exemples I will definitively use:</p>
<p>Defining a Sharepoint Service account role which include both security administrator role and dbcreator role:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE [master] <br />
GO <br />
CREATE SERVER ROLE [SharepointService] <br />
GO <br />
ALTER SERVER ROLE [dbcreator] ADD MEMBER [SharepointService] <br />
ALTER SERVER ROLE [securityadmin] ADD MEMBER [SharepointService] <br />
GO</div></div>
<p>Defining a profiler user role:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE SERVER ROLE ProfilerUsers <br />
GO <br />
GRANT ALTER TRACE to ProfilerUsers</div></div>
<p>I&rsquo;m pretty sure there&rsquo;s a bunch of other roles which can be usefull, like a linked server manager role, and I&rsquo;m glad to see this new feature available!</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event log permissions</title>
		<link>https://blog.developpez.com/dje/p9163/ms-sql-server/event_log_permissions</link>
		<comments>https://blog.developpez.com/dje/p9163/ms-sql-server/event_log_permissions#comments</comments>
		<pubDate>Thu, 29 Jul 2010 11:47:25 +0000</pubDate>
		<dc:creator><![CDATA[Ptit_Dje]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il est parfois requis de definir une securite personnalisee au niveau des journaux de l&#8217;event viewer de windows. Pour ce faire nous allons tout d&#8217;abord nous servir de la commande getsid dans une fenetre CMD comme ceci: getsid \\ServerName (AD)Group/User \\ServerName (AD)User/Group Exemple: getsid \\Server1 GroupeDeveloppeur \\Server1 UtilisateurX Cette commande va retourner le SID attribue sur le Server1 pour le groupe GroupeDeveloppeur et l&#8217;utilisateur UtilisateurX. La definition des permissions sur les journaux d&#8217;evenement se fait [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Il est parfois requis de definir une securite personnalisee au niveau des journaux de l&rsquo;event viewer de windows.</p>
<p>Pour ce faire nous allons tout d&rsquo;abord nous servir de la commande getsid dans une fenetre CMD comme ceci:<br />
getsid \\ServerName (AD)Group/User \\ServerName (AD)User/Group<br />
Exemple: getsid \\Server1 GroupeDeveloppeur \\Server1 UtilisateurX</p>
<p>Cette commande va retourner le SID attribue sur le Server1 pour le groupe GroupeDeveloppeur et l&rsquo;utilisateur UtilisateurX.</p>
<p>La definition des permissions sur les journaux d&rsquo;evenement se fait au niveau de la registry de windows, au niveau de la clef:<br />
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\{LogName} -> customSD<br />
Ou LogName est le nom du fichier log sur lequel on veut attribuer des permissions specifiques.</p>
<p>On va ajouter a la valeur contenue dans customSD la chaine suivante:<br />
({TypePermission};;{Acces};;;{SID})<br />
Ou:<br />
{TypePermission} est soit A pour autoriser soit D pour refuser l&rsquo;acces.<br />
{Acces} est la valeur en hexadecimal des acces que l&rsquo;on souhaite autoriser ou refuser bases sur les valeurs suivantes:<br />
1 &#8211; Lecture<br />
2 &#8211; Ecriture<br />
4 &#8211; Effacement.</p>
<p>Soit pour autoriser l&rsquo;acces en lecture a l&rsquo;utilisateur ayant un SID de 1-2-3456 pour le journal MonJournal, on va aller dans la base de registre au niveau de la clef HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\MonJournal et rajouter a la valeur de CustomSD:<br />
(A;;0x1;;;1-2-3456)  </p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
