<?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>David Barbarin &#187; PowerShell</title>
	<atom:link href="https://blog.developpez.com/mikedavem/pcategory/sql-server-2005/architecture/powershell/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/mikedavem</link>
	<description>MVP DataPlatform - MCM SQL Server</description>
	<lastBuildDate>Thu, 09 Sep 2021 21:19:50 +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>AAD user creation on behalf AAD Service Principal with Azure SQL DB</title>
		<link>https://blog.developpez.com/mikedavem/p13197/sql-azure/aad-user-creation-on-behalf-aad-service-principal-with-azure-sql-db</link>
		<comments>https://blog.developpez.com/mikedavem/p13197/sql-azure/aad-user-creation-on-behalf-aad-service-principal-with-azure-sql-db#comments</comments>
		<pubDate>Sun, 02 Aug 2020 22:28:06 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Azure Automation]]></category>
		<category><![CDATA[Azure SQL Database]]></category>
		<category><![CDATA[Azure SQL DB]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Runbook]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Service Principal]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[System managed identity]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/mikedavem/?p=1643</guid>
		<description><![CDATA[An interesting improvement was announced by the SQL AAD team on Monday 27th July 2020 and concerns the support for Azure AD user creation on behalf of Azure AD Applications for Azure SQL as mentioned to this Microsoft blog post. &#8230; <a href="https://blog.developpez.com/mikedavem/p13197/sql-azure/aad-user-creation-on-behalf-aad-service-principal-with-azure-sql-db">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>An interesting improvement was announced by the SQL AAD team on Monday 27th July 2020 and concerns the support for Azure AD user creation on behalf of Azure AD Applications for Azure SQL as mentioned to this <a href="https://techcommunity.microsoft.com/t5/azure-sql-database/support-for-azure-ad-user-creation-on-behalf-of-azure-ad/ba-p/1491121" rel="noopener" target="_blank">Microsoft blog post</a>. </p>
<p><span id="more-1643"></span></p>
<p>In my company, this is something we were looking for a while with our database refresh process in Azure. Before talking this new feature, let me share a brief history of different considerations we had for this DB refresh process over the time with different approaches we went through. First let’s precise DB Refresh includes usually at least two steps: restoring backup / copying database – you have both ways in Azure SQL Database – and realigning security context with specific users regarding your targeted environment (ACC / INT …).  But the latter is not as trivial as you may expect if you opted to use either a SQL Login / User or a Service Principal to carry out this operation in your process. Indeed, in both cases creating an Azure AD User or Group is not supported, and if you try you will face this error message:</p>
<blockquote><p>‘’ is not a valid login or you do not have permission. </p></blockquote>
<p>All the stuff (either Azure automation runbook and PowerShell modules on-prem) done so far and described afterwards meets the same following process:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/08/164-1-DB-Refresh-process-e1596406580306.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/08/164-1-DB-Refresh-process-e1596406580306.jpg" alt="164 - 1 - DB Refresh process" width="800" height="566" class="alignnone size-full wp-image-1645" /></a></p>
<p>First, we used Invoke-SQCMD in Azure Automation runbook with T-SQL query to create a copy of a source database to the target server. T-SQL is mandatory in this case as per <a href="https://docs.microsoft.com/en-us/azure/azure-sql/database/database-copy?tabs=azure-powershell" rel="noopener" target="_blank">documented</a> in the Microsoft BOL because PROD and ACC or INT servers are not on the same subscription. Here a simplified sample of code:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
$CopyDBCMD = @{<br />
&nbsp; &nbsp; 'Database' = 'master'<br />
&nbsp; &nbsp; 'ServerInstance' = $TargetServerName<br />
&nbsp; &nbsp; 'Username' = $SQLUser<br />
&nbsp; &nbsp; 'Password' = $SQLPWD<br />
&nbsp; &nbsp; 'Query' = 'CREATE DATABASE '+ '[' + $DatabaseName + '] ' + 'AS COPY OF ' + '[' + $SourceServerName + '].[' + $DatabaseName + ']'<br />
} <br />
<br />
Invoke-Sqlcmd @CopyDBCMD <br />
...</div></div>
<p>But as you likely know, Invoke-SQLCMD doesn’t support AAD authentication and because SQL Login authentication was the only option here, it led us dealing with an annoying issue about the security configuration step with AAD users or groups as you may imagine. </p>
<p>Then, because we based authentication mainly on trust architecture and our security rules require using it including apps with managed identities or service principals, we wanted also to introduce this concept to our database refresh process. Fortunately, service principals are supported with <a href="https://techcommunity.microsoft.com/t5/azure-sql-database/token-based-authentication-support-for-azure-sql-db-using-azure/ba-p/386091" rel="noopener" target="_blank">Azure SQL DBs since v12</a> with access token for authentication by ADALSQL. The corresponding DLL is required on your server or if you use it from Azure Automation like us, we added the ADAL.PS module but be aware it is now deprecated, and I advise you to strongly invest in moving to MSAL. Here a sample we used:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
$response = Get-ADALToken `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -ClientId $clientId `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -ClientSecret $clientSecret `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -Resource $resourceUri `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -Authority $authorityUri `<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -TenantId $tenantName<br />
<br />
...<br />
<br />
$connectionString = &quot;Server=tcp:$SqlInstanceFQDN,1433;Initial Catalog=master;Persist Security Info=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;&quot;<br />
# Create the connection object<br />
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)<br />
# Set AAD generated token to SQL connection token<br />
$connection.AccessToken = $response.AccessToken<br />
<br />
Try {<br />
&nbsp; &nbsp; $connection.Open()<br />
&nbsp; &nbsp; ...<br />
} <br />
...</div></div>
<p>But again, even if the copy or restore steps are well managed, we still got stuck with security reconfiguration, because service principals were not supported for creating AAD users or groups so far &#8230;</p>
<p>In the meantime, we found out a temporary and interesting solution based on <a href="https://dbatools.io/" rel="noopener" target="_blank">dbatools framework</a> and the <a href="https://docs.dbatools.io/#Invoke-DbaQuery" rel="noopener" target="_blank">Invoke-dbaquery command</a> which supports AAD authentication (Login + Password). As we may not rely on service principal in this case, using a dedicated AAD account was an acceptable tradeoff to manage all the database refresh process steps. But going through this way comes with some disadvantages because running Invoke-dbaquery in a full Azure automation mode is not possible with missing ADALsql.dll. Workaround may be to use hybrid-worker, but we didn’t want to add complexity to our current architecture only for this special case. Instead we decided to move the logic of the Azure automation runbook into on-prem PowerShell framework which already include logic for DB refresh for on-prem SQL Server instances. </p>
<p>Here a simplified sample of code we are using:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
Try {<br />
&nbsp; &nbsp; # Connect to get access to Key Vault info<br />
&nbsp; &nbsp; Connect-AzAccount | Out-Null<br />
<br />
&nbsp; &nbsp; [String]$user = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-SQLBCKUSER&quot;).SecretValueText<br />
&nbsp; &nbsp; [System.Security.SecureString]$pwd = &nbsp;ConvertTo-SecureString (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-SQLBCKPWD&quot;).SecretValueText -AsPlainText -Force<br />
&nbsp; &nbsp; [String]$SourceServerName = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-NAME&quot;).SecretValueText<br />
&nbsp; &nbsp; [String]$TargetServerName = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-TARGETNAME&quot;).SecretValueText + '.database.windows.net'<br />
<br />
&nbsp; &nbsp; # DB Restore will be performed in the context of dedicated AAD account <br />
&nbsp; &nbsp; $pscredential = New-Object -TypeName System.Management.Automation.PSCredential($user, $pwd)<br />
<br />
&nbsp; &nbsp; Write-Host &quot;Restoring DB:$DatabaseName from Source Server: $SourceServerName to Target Server: $TargetServerName&quot;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; $Query = &quot;CREATE DATABASE [$DatabaseName] AS COPY OF [$SourceServerName].[$DatabaseName]&quot;<br />
&nbsp; &nbsp; Invoke-DbaQuery `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -SqlInstance $TargetServerName `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -Database master `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -SqlCredential $pscredential `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -Query $Query `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -EnableException <br />
<br />
&nbsp; &nbsp; # Wait for DB online and ready ... <br />
&nbsp; &nbsp; # Code should be implemented for this check <br />
<br />
<br />
&nbsp; &nbsp; Write-Output &quot;Applying security configuration to DB: $DatabaseName on Server:$TargetServerName&quot;<br />
<br />
&nbsp; &nbsp; $Query = &quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; DROP USER [az_sql_ro];CREATE USER [az_sql_ro] FROM EXTERNAL PROVIDER;<br />
&nbsp; &nbsp; &quot;<br />
&nbsp; &nbsp; Invoke-DbaQuery `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -SqlInstance $TargetServerName `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -Database $DatabaseName `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -SqlCredential $pscredential `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -Query $Query `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -EnableException<br />
<br />
}<br />
Catch {<br />
&nbsp; &nbsp; Write-Host &quot;Error encountered: $($_.Exception.Message)&quot;<br />
} <br />
...</div></div>
<p>Referring to the PowerShell code above, in the second step, we create an AAG group [az_sql_ro] on behalf of the AAD dedicated account with the CLAUSE FROM EXTERNAL PROVIDER. </p>
<p>Finally, with the latest news published by the SQL AAD team, we will likely consider using back service principal instead of dedicated Windows AAD account. <a href="https://techcommunity.microsoft.com/t5/azure-sql-database/support-for-azure-ad-user-creation-on-behalf-of-azure-ad/ba-p/1491121" rel="noopener" target="_blank">This Microsoft blog post</a> explains in details how it works and what you have to setup to make it work correctly. I don’t want to duplicate what is already explained so I will apply the new stuff to my context. </p>
<p>Referring to the above blog post, you need first to setup a server identity for your Azure SQL Server as below:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Set-AzSqlServer `<br />
&nbsp; &nbsp; -ResourceGroupName sandox-rg `<br />
&nbsp; &nbsp; -ServerName a-s-sql02 `<br />
&nbsp; &nbsp; -AssignIdentity<br />
<br />
# Check server identity<br />
Get-AzSqlServer `<br />
&nbsp; &nbsp; -ResourceGroupName sandox-rg `<br />
&nbsp; &nbsp; -ServerName a-s-sql02 | `<br />
&nbsp; &nbsp; Select-Object ServerName, Identity</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ServerName Identity &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
---------- -------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
a-s-sql02 &nbsp;Microsoft.Azure.Management.Sql.Models.ResourceIdentity</div></div>
<p>Let&rsquo;s have a look at the server identity</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># Get identity details<br />
$identity = Get-AzSqlServer `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -ResourceGroupName sandox-rg `<br />
&nbsp; &nbsp; &nbsp; &nbsp; -ServerName a-s-sql02<br />
<br />
$identity.identity</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">PrincipalId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Type &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TenantId &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
----------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;---- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -------- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
7f0d16f7-b172-4c97-94d3-34f0f7ed93cf SystemAssigned 2fcd19a7-ab24-4aef-802b-6851ef5d1ed5</div></div>
<p>In fact, assigning a server identity means creating a system assigned managed identity in the Azure AD tenant that&rsquo;s trusted by the subscription of the instance. To keep things simple, let’s say that System Managed Identity in Azure is like to Managed Account or Group Managed Account on-prem. Those identities are self-managed by the system. Then you need to grant this identity the Azure AD &laquo;&nbsp;Directory Readers &laquo;&nbsp;permission to get rights for creating AAD Users or Groups on behalf of this identity. A PowerShell script is provided by Microsoft <a href="https://docs.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-service-principal-tutorial" rel="noopener" target="_blank">here</a> a sample of code I applied in my context for testing:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:650px;height:450px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
Try {<br />
&nbsp; &nbsp; $DatabaseName = &quot;test-DBA&quot; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; # Connect to get access to Key Vault info<br />
&nbsp; &nbsp; Connect-AzAccount | Out-Null<br />
<br />
&nbsp; &nbsp; [String]$user = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-SQLBCKAPPID&quot;).SecretValueText<br />
&nbsp; &nbsp; [System.Security.SecureString]$pwd = &nbsp;ConvertTo-SecureString (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-SQLBCKAPPSECRET&quot;).SecretValueText -AsPlainText -Force<br />
&nbsp; &nbsp; [String]$SourceServerName = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-NAME&quot;).SecretValueText<br />
&nbsp; &nbsp; [String]$TargetServerName = (Get-AzKeyVaultSecret -VaultName $KeyvaultName -Name &quot;AZSQL-TARGETNAME&quot;).SecretValueText + '.database.windows.net'<br />
<br />
&nbsp; &nbsp; # DB Restore will be performed in the context of dedicated AAD account <br />
&nbsp; &nbsp; $pscredential = New-Object -TypeName System.Management.Automation.PSCredential($user, $pwd)<br />
<br />
&nbsp; &nbsp; $adalPath &nbsp;= &quot;${env:ProgramFiles}\WindowsPowerShell\Modules\Az.Profile.7.0\PreloadAssemblies&quot;<br />
&nbsp; &nbsp; # To install the latest AzureRM.profile version execute &nbsp;-Install-Module -Name AzureRM.profile<br />
&nbsp; &nbsp; $adal &nbsp; &nbsp; &nbsp;= &quot;$adalPath\Microsoft.IdentityModel.Clients.ActiveDirectory.dll&quot;<br />
&nbsp; &nbsp; $adalforms = &quot;$adalPath\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll&quot;<br />
&nbsp; &nbsp; [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null<br />
&nbsp; &nbsp; $resourceAppIdURI = 'https://database.windows.net/'<br />
<br />
&nbsp; &nbsp; # Set Authority to Azure AD Tenant<br />
&nbsp; &nbsp; $authority = 'https://login.windows.net/' + $tenantId<br />
<br />
&nbsp; &nbsp; $ClientCred = [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential]::new($clientId, $clientSecret)<br />
&nbsp; &nbsp; $authContext = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new($authority)<br />
&nbsp; &nbsp; $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$ClientCred)<br />
&nbsp; &nbsp; $Tok = $authResult.Result.CreateAuthorizationHeader()<br />
&nbsp; &nbsp; $Tok=$Tok.Replace(&quot;Bearer &quot;,&quot;&quot;)<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; Write-host &quot;Token generated is ...&quot;<br />
&nbsp; &nbsp; $Tok<br />
&nbsp; &nbsp; Write-host &nbsp;&quot;&quot;<br />
<br />
&nbsp; &nbsp; Write-Host &quot;Create SQL connectionstring&quot;<br />
&nbsp; &nbsp; $conn = New-Object System.Data.SqlClient.SQLConnection <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; $conn.ConnectionString = &quot;Data Source=$TargetServerName;Initial Catalog=master;Connect Timeout=30&quot;<br />
&nbsp; &nbsp; $conn.AccessToken = $Tok<br />
<br />
&nbsp; &nbsp; Write-host &quot;Connect to database and execute SQL script&quot;<br />
&nbsp; &nbsp; $conn.Open() <br />
<br />
&nbsp; &nbsp; Write-Host &quot;Check connected user ...&quot;<br />
&nbsp; &nbsp; $Query = &quot;SELECT USER_NAME() AS [user_name];&quot;<br />
&nbsp; &nbsp; $command = New-Object -TypeName System.Data.SqlClient.SqlCommand($Query, $conn)<br />
&nbsp; &nbsp; $Command.ExecuteScalar()<br />
&nbsp; &nbsp; $conn.Close()<br />
<br />
&nbsp; &nbsp; Write-Host &quot;Restoring DB:$DatabaseName from Source Server: $SourceServerName to Target Server: $TargetServerName&quot;<br />
<br />
&nbsp; &nbsp; $conn.ConnectionString = &quot;Data Source=$TargetServerName;Initial Catalog=master;Connect Timeout=30&quot;<br />
&nbsp; &nbsp; $conn.AccessToken = $Tok<br />
&nbsp; &nbsp; $conn.Open()<br />
&nbsp; &nbsp; $Query = &quot;DROP DATABASE IF EXISTS [$DatabaseName]; CREATE DATABASE [$DatabaseName] AS COPY OF [$SourceServerName].[$DatabaseName]&quot;<br />
&nbsp; &nbsp; $command = New-Object -TypeName System.Data.SqlClient.SqlCommand($Query, $conn)<br />
&nbsp; &nbsp; $command.CommandTimeout = 1200<br />
&nbsp; &nbsp; $command.ExecuteNonQuery()<br />
&nbsp; &nbsp; $conn.Close()<br />
<br />
&nbsp; &nbsp; # Wait for DB online and ready ... <br />
&nbsp; &nbsp; # Code should be implemented for this check <br />
<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; Write-Output &quot;Applying security configuration to DB: $DatabaseName on Server:$TargetServerName&quot;<br />
<br />
&nbsp; &nbsp; $conn.ConnectionString = &quot;Data Source=$TargetServerName;Initial Catalog=$DatabaseName;Connect Timeout=30&quot;<br />
&nbsp; &nbsp; $conn.AccessToken = $Tok<br />
&nbsp; &nbsp; $conn.Open() <br />
&nbsp; &nbsp; $Query = 'CREATE USER [az_sql_ro] FROM EXTERNAL PROVIDER;'<br />
&nbsp; &nbsp; $command = New-Object -TypeName System.Data.SqlClient.SqlCommand($Query, $conn) &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; $command.ExecuteNonQuery()<br />
&nbsp; &nbsp; $conn.Close()<br />
<br />
}<br />
Catch {<br />
&nbsp; &nbsp; Write-Output &quot;Error encountered: $($_.Exception.Message)&quot;<br />
} <br />
...</div></div>
<p>Using service principal required few changes in my case. I now get credentials of the service principal (ClientId and Secret) from Azure Key Vault instead of the AAD dedicated account used in previous example. I also changed the way to connect to SQL Server by relying on ADALSQL to get the access token instead of using dbatools commands. Indeed, as far as I know, dbatools doesn’t support this authentication way (yet?). </p>
<p>The authentication process becomes as follows:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/08/164-3-new-auth-process-e1596407082747.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/08/164-3-new-auth-process-e1596407082747.jpg" alt="164 - 3 - new auth process" width="800" height="610" class="alignnone size-full wp-image-1647" /></a></p>
<p>My first test seems to be relevant:</p>
<p><a href="http://blog.developpez.com/mikedavem/files/2020/08/164-4-test-with-SP-e1596407153885.jpg"><img src="http://blog.developpez.com/mikedavem/files/2020/08/164-4-test-with-SP-e1596407153885.jpg" alt="164 - 4 - test with SP" width="800" height="301" class="alignnone size-full wp-image-1648" /></a></p>
<p>This improvement looks promise and may cover broader scenarios as the one I described in this blog post. This feature is in preview at the moment of this write-up and I hope to see it coming soon in GA as well as a potential support of preferred PowerShell framework DBAtools <img src="https://blog.developpez.com/mikedavem/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>See you!</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL Server PowerShell : Récupérer la volumétrie globale des serveurs SQL</title>
		<link>https://blog.developpez.com/mikedavem/p8991/sql-server-2005/architecture/powershell/sql_server_powershell_recuperer_la_volum</link>
		<comments>https://blog.developpez.com/mikedavem/p8991/sql-server-2005/architecture/powershell/sql_server_powershell_recuperer_la_volum#comments</comments>
		<pubDate>Sat, 12 Jun 2010 11:35:49 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un collègue qui est chargé de rationnaliser les processus d&#8217;entreprises autour des serveurs de bases de données m&#8217;a demandé s&#8217;il était possible de connaître la volumétrie de chaque serveur SQL Server en terme d&#8217;espace disque et la volumétrie globale de &#8230; <a href="https://blog.developpez.com/mikedavem/p8991/sql-server-2005/architecture/powershell/sql_server_powershell_recuperer_la_volum">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><font size="2">Un collègue qui est chargé de rationnaliser les processus d&rsquo;entreprises autour des serveurs de bases de données m&rsquo;a demandé s&rsquo;il était possible de connaître la volumétrie de chaque serveur SQL Server en terme d&rsquo;espace disque et la volumétrie globale de l&rsquo;ensemble de ces serveurs. L&rsquo;idée ici est d&rsquo;avoir une idée de la volumétrie d&rsquo;espace disque pour chaque technologie de bases de données (SQL Server et Oracle notamment). Je vous propose ici un script PowerShell permettant de réaliser cette tâche.</font></p>
<p><span id="more-124"></span></p>
<p><font size="2">Ce script s&rsquo;exécute avec la version 2.0 de PowerShell. Il faut également avoir installé les outils de management de SQL Server 2008.</font></p>
<p><font size="2">Ce script prend en paramètres d&rsquo;entrées :</font></p>
<p><font size="2">- Un fichier texte comportant la liste des serveurs SQL recensés dans l&rsquo;entreprise (<strong><em>sql_server.txt</em></strong>)       <br />- Un script SQL permettant de récupérer la volumétrie globale de chaque serveur pour l&rsquo;ensemble des bases de données systèmes et utilisateurs. (<strong><em>size_serveur.sql</em></strong>)</font></p>
<p><font size="2">. et il délivre en sortie :</font></p>
<p><font size="2">- Un affichage dans la console pour chaque serveur joignable, la version de SQL Server et sa volumétrie globale      <br />- Un fichier log (SqlLog.txt). Dans ce fichier existe une entrée pour chaque serveur où il s&rsquo;est produit une erreur (Serveur inacessible, compte de connexion incorrect, erreur d&rsquo;exécution du script SQL etc..).</font></p>
<p><font size="2">Le script SQL (size_serveur.sql) :</font></p>
<blockquote><p><font size="2"><strong>/************************************************          <br />* @Author = BARBARIN David                     *           <br />* @Description =                               *           <br />* Récupération de la version du serveur SQL +  *           <br />* volumétrie globale de l&rsquo;ensemble des bases   *           <br />* des données (fichiers DATA + LOG)            *           <br />************************************************/ </strong></font></p>
<p><font size="2"><strong>DECLARE @version TINYINT </strong></font></p>
<p><font size="2"><strong>SELECT @version = CAST(RIGHT(LEFT(@@VERSION, CHARINDEX(&lsquo;.&rsquo;, @@VERSION) &#8211; 1), 2) AS TINYINT) </strong></font></p>
<p><font size="2"><strong>&#8211; Version inférieur à SQL Server 2005          <br />IF (@version &lt; 9)           <br />BEGIN           <br />SELECT           <br />    @@VERSION AS version_sql,           <br />    CAST(SUM(size) * 8. / 1024 / 1024 AS DECIMAL(15,2)) AS size_GB           <br />FROM master..sysaltfiles           <br />END           <br />&#8211; Version supérieure ou égale à SQL Server 2005           <br />ELSE           <br />BEGIN           <br />SELECT           <br />    @@VERSION AS version_sql,           <br />    CAST(SUM(size) * 8. / 1024 / 1024 AS DECIMAL(15,2)) AS size_GB           <br />FROM sys.master_files           <br />END</strong></font></p>
</blockquote>
<p><font size="2"> </font></p>
<p><font size="2">Le script PowerShell (volumetrie_sqlserver.ps1) :</font></p>
<blockquote><p><font size="2"><strong>####################################          <br /># @author = David BARBARIN                                  #           <br /># @Description =                                                   #           <br /># Volumétrie globale par serveur                              #           <br /># et totale                                                            #           <br /># @PARAM =                                                         #           <br /># Fichier texte contenant la liste                              #           <br /># des serveurs SQL                                                #           <br /># @OUTPUT =                                                       #           <br /># Nom du serveur + version                                    #           <br /># Volumétrie par serveur                                         #           <br /># Volumétrie globale                                             #           <br /># Erreurs dans fichier log                                        #           <br /># SqlLog.txt                                                         #           <br />################################### </strong></font></p>
<p><strong><font size="2"># Désactivation des messages d&rsquo;erreurs sur la console PowerShell         <br />$ErrorActionPreference = &laquo;&nbsp;SilentlyContinue&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2"># Chargement des snapin pour SQL Server         <br />Add-PSSnapin SqlServerCmdletSnapin100          <br />Add-PSSnapin SqlServerProviderSnapin100 </font></strong></p>
<p><strong><font size="2"># Récupération de la liste des serveurs         <br />$servers = get-content &laquo;&nbsp;sql_server.txt&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2"># Path courant         <br />$path = Get-Location </font></strong></p>
<p><strong><font size="2"># Username et Password         <br />$credentialsql = &laquo;&nbsp;&nbsp;&raquo; # Pour une authentification de type Windows -> $credentialsql = &laquo;&nbsp;Windows&nbsp;&raquo;          <br />$username = &laquo;&nbsp;user&nbsp;&raquo;          <br />$password = &laquo;&nbsp;password&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2">$result_final = 0 </font></strong></p>
<p><strong><font size="2"># Initialisation fichier         <br />$date = get-date          <br />Write-output &laquo;&nbsp;Erreur log du $date&nbsp;&raquo; | out-File &laquo;&nbsp;$path\SqlLog.txt&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2"># Pour chaque serveur on récupère les informations de volumétrie         <br />foreach($server in $servers)          <br />{          <br /> $error.Clear()          <br /> try {          <br />  # Exécution script sql de récupération volumétrie données.          <br />  if ($credentialsql -eq &laquo;&nbsp;Windows&nbsp;&raquo;)          <br />  {          <br />   $result = Invoke-Sqlcmd -ServerInstance $server -inputFile &laquo;&nbsp;$path\size_serveur.sql&nbsp;&raquo; -OutputSqlErrors $false          <br />  }          <br />  else          <br />  {          <br />   $result = Invoke-Sqlcmd -Username $username -Password $password -ServerInstance $server -inputFile &laquo;&nbsp;$path\size_serveur.sql&nbsp;&raquo; -OutputSqlErrors $false          <br />  }          <br />  # Affichage du résultat dans la fenêtre Powershell          <br />  Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />  Write-Host &laquo;&nbsp;Serveur : &nbsp;&raquo; $server          <br />  Write-Host &laquo;&nbsp;Version : &nbsp;&raquo; $result.version_sql          <br />  Write-Host &laquo;&nbsp;Volumétrie serveur : &nbsp;&raquo; $result.size_GB &laquo;&nbsp;GB&nbsp;&raquo;          <br />  # Comptabilisation du volume de données global           <br />  $result_final = $result_final + $result.size_GB          <br /> }          <br /> catch           <br /> {          <br />  # Affichage erreur dans la fenêtre PowerShell          <br />  Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />  Write-Host &laquo;&nbsp;Serveur : &nbsp;&raquo; $server          <br />  Write-Host &laquo;&nbsp;Problème de récupération des données. Vérifiez le journal d&rsquo;erreurs SqlLog.txt&nbsp;&raquo;          <br />  # Enregistrement détail de l&rsquo;erreur dans le fichier log           <br />  $message = &laquo;&nbsp;&#8212; Erreur de récupération pour le serveur : $server . $error&nbsp;&raquo;          <br />  Write-output $message | out-File -append &laquo;&nbsp;$path\SqlLog.txt&nbsp;&raquo;    <br /> }          <br /> Finally {          <br />  Continue          <br /> }    <br />} </font></strong></p>
<p><strong><font size="2"># Affichage volumétrie globale dans la fenêtre Powershell         <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;Volumétrie total : &nbsp;&raquo; $result_final &laquo;&nbsp;GB&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2"># Suppression des snapin pour SQL Server         <br />Remove-PSSnapin SqlServerCmdletSnapin100          <br />Remove-PSSnapin SqlServerProviderSnapin100</font></strong></p>
</blockquote>
<p><font size="2"> </font></p>
<p><font size="2">Bon audit !! </font></p>
<p><font size="2">David BARBARIN (Mikedavem)     <br />Elève ingénieur CNAM Lyon</font></p>
<p><font size="2"></font></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL Server PowerShell : Comment récupérer rapidement les informations générales d’une liste de serveurs</title>
		<link>https://blog.developpez.com/mikedavem/p8962/sql-server-2008-r2/sql_server_powershell_comment_recuperer</link>
		<comments>https://blog.developpez.com/mikedavem/p8962/sql-server-2008-r2/sql_server_powershell_comment_recuperer#comments</comments>
		<pubDate>Tue, 01 Jun 2010 20:06:51 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server 2008 R2]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il y a peu de temps j&#8217;ai dû effectué un audit sur un ensemble de serveurs SQL. Autant vous dire que j&#8217;ai essayé d&#8217;optimiser certaines tâches comme la récupération de certaines données générales du serveur comme les processeurs, la mémoire, &#8230; <a href="https://blog.developpez.com/mikedavem/p8962/sql-server-2008-r2/sql_server_powershell_comment_recuperer">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><font size="2">Il y a peu de temps j&rsquo;ai dû effectué un audit sur un ensemble de serveurs SQL. Autant vous dire que j&rsquo;ai essayé d&rsquo;optimiser certaines tâches comme la récupération de certaines données générales du serveur comme les processeurs, la mémoire, les disques et le système d&rsquo;exploitation. Voici un script Powershell qui permet de récupérer ces informations rapidement !!</font></p>
<p><span id="more-123"></span><br />
<font size="2"></font>
<p><font size="2">Le script utilise un fichier nommé <strong>sqlserver.txt</strong> dans lequel il suffit de mettre les noms des serveurs SQL à auditer. Assurer vous également que le compte utilisé par le script ait les droits nécessaires pour interroger du cmdlet sur le serveur concerné. Ce script a été testé sur Windows 2003 Server, Windows Server 2008  et Windows Server 2008 R2.</font></p>
<blockquote><p><strong><font size="2">#################################          <br /># @author = Mikedavem           #           <br /># @Description =                #           <br /># Récupération d&rsquo;informations   #           <br /># serveurs (CPU, mémoire,       #           <br /># disques, OS &#8230;)              #           <br />################################# </font></strong></p>
<p><strong><font size="2">$computername = &laquo;&nbsp;computername&nbsp;&raquo;;          <br />$login = &laquo;&nbsp;domain\administrateur&nbsp;&raquo;           <br />$pwd = convertto-securestring &laquo;&nbsp;pasword&nbsp;&raquo; -asplaintext -force;           <br />$servers = get-content &laquo;&nbsp;sql_server.txt&nbsp;&raquo; </font></strong></p>
<p><strong><font size="2"># Définition du crédential          <br />$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $login,$pwd -ErrorAction &laquo;&nbsp;silentlycontinue&nbsp;&raquo;; </font></strong></p>
<p><strong><font size="2">foreach($server in $servers)          <br />{           <br />$operatingSystem = get-wmiobject win32_OperatingSystem -computername $server -credential $credential           <br />Write-Host $operatingSystem.CSName           <br />Write-Host $operatingSystem.Caption           <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;           <br />Write-Host &laquo;&nbsp;Disques : &nbsp;&raquo; </font></strong></p>
<p><strong><font size="2">$Disk = get-WmiObject Win32_LogicalDisk -computername $server -credential $credential | Where {$_.Name -ne &laquo;&nbsp;A:&nbsp;&raquo; -and $_.DriveType -eq &laquo;&nbsp;3&nbsp;&raquo;} </font></strong></p>
<p><strong><font size="2">foreach ( $disque in $Disk ) {          <br />    # calul de la taille en Giga octet           <br />    $taille = $disque.freespace / (1024*1024*1024)           <br />    $taille = [math]::round($taille, 1) # Arrondi la taille à la décimale           <br />    $size = $disque.size / (1024*1024*1024)           <br />    $size = [math]::round($size, 1) </font></strong></p>
<p><strong><font size="2">    Write-host &laquo;&nbsp;Drive=&nbsp;&raquo; $disque.Name &laquo;&nbsp;Size=&nbsp;&raquo; $size &laquo;&nbsp;Go FreeSpace=&nbsp;&raquo; $taille &laquo;&nbsp;Go&nbsp;&raquo;          <br />} </font></strong></p>
<p><strong><font size="2">Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;CPU : &nbsp;&raquo; </font></strong></p>
<p><strong><font size="2">$processor = get-wmiobject Win32_processor -computername $server -credential $credential          <br />foreach ($proc in $processor)           <br />{           <br />  Write-Host &laquo;&nbsp;ID=&nbsp;&raquo; $proc.DeviceID &laquo;&nbsp;Proc=&nbsp;&raquo; $proc.Name &laquo;&nbsp;, Speed=&nbsp;&raquo;$proc.CurrentClockSpeed&nbsp;&raquo;MHz Arch=&nbsp;&raquo; -nonewline;           <br />  Switch($proc.Architecture)           <br />             {           <br />              0{&laquo;&nbsp;x86&Prime;}           <br />              1{&laquo;&nbsp;MIPS&nbsp;&raquo;}           <br />              2{&laquo;&nbsp;Alpha&nbsp;&raquo;}           <br />              3{&laquo;&nbsp;PowerPC&nbsp;&raquo;}           <br />              6{&laquo;&nbsp;Intel Itanium IPF&nbsp;&raquo;}           <br />              9{&laquo;&nbsp;x64&Prime;}           <br />             }           <br />} </font></strong></p>
<p><strong><font size="2">Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;          <br />Write-Host &laquo;&nbsp;Memory : &nbsp;&raquo;           <br />$memory = get-wmiobject Win32_ComputerSystem -computername $server -credential $credential           <br />foreach ($mem in $memory)           <br />{           <br />  $tailleRAM = [math]::round($mem.TotalPhysicalMemory / (1024 * 1024 * 1024), 1)           <br />  Write-Host &laquo;&nbsp;Total of memory =&nbsp;&raquo; $tailleRAM &laquo;&nbsp;Go&nbsp;&raquo;;           <br />}           <br />Write-Host &laquo;&nbsp;&#8212;&#8212;&#8212;&nbsp;&raquo;           <br />Write-Host &laquo;&nbsp;&nbsp;&raquo;           <br />}</font></strong></p>
</blockquote>
<p><font size="2">Bon audit !!</font></p>
<p><font size="2">David BARBARIN (Mikedavem)      <br />Elève ingénieur CNAM</font></p>
<p><font size="2"></font></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL Server PowerShell : Activer désactiver certains protocoles SQL Server</title>
		<link>https://blog.developpez.com/mikedavem/p8961/sql-server-2005/architecture/powershell/sql_server_powershell_activer_desactiver</link>
		<comments>https://blog.developpez.com/mikedavem/p8961/sql-server-2005/architecture/powershell/sql_server_powershell_activer_desactiver#comments</comments>
		<pubDate>Tue, 01 Jun 2010 18:52:15 +0000</pubDate>
		<dc:creator><![CDATA[mikedavem]]></dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sur certaines éditions de SQL Server, l&#8217;activation du protocole TCPIP requiert une action manuelle. Voici un script powershell qui peut être intégré à une installation automatique et qui active le protocole TCPIP d&#8217;une part et désactive les canaux nommés d&#8217;autre &#8230; <a href="https://blog.developpez.com/mikedavem/p8961/sql-server-2005/architecture/powershell/sql_server_powershell_activer_desactiver">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><font size="2">Sur certaines éditions de SQL Server, l&rsquo;activation du protocole TCPIP requiert une action manuelle. Voici un script powershell qui peut être intégré à une installation automatique et qui active le protocole TCPIP d&rsquo;une part et désactive les canaux nommés d&rsquo;autre part.</font></p>
<p><span id="more-24"></span>
<p><font size="2">Ce script prend en paramètre le nom du serveur ainsi qu&rsquo;un compte de connexion et mot de passe. Ce compte doit être administrateur du serveur en local pour pouvoir accéder à l&rsquo;espace de nom &laquo;&nbsp;<strong><em>root\Microsoft\SqlServer\ComputerManagement</em></strong>&laquo;&nbsp;. De plus, il faudra penser à changer l&rsquo;espace de nom en &laquo;&nbsp;<strong><em>root\Microsoft\SqlServer\ComputerManagement10</em></strong>&nbsp;&raquo; pour SQL Server 2008 et SQL Server 2008 R2. Enfin ce script n&rsquo;opère que sur l&rsquo;instance par défaut.</font></p>
<blockquote><p><strong><font size="2">#################################          <br /># @author = Mikedavem           #           <br /># @Description =                #           <br /># Activation du protocole TCPIP #           <br /># et désactiviation des canaux  #           <br /># nommés.                       #           <br />################################# </font></strong></p>
<p><strong><font size="2">$computername = &laquo;&nbsp;computeurname&nbsp;&raquo;;          <br />$login = &laquo;&nbsp;domain\administrateur&nbsp;&raquo;           <br />$pwd = convertto-securestring &laquo;&nbsp;pass&nbsp;&raquo; -asplaintext -force; </font></strong></p>
<p><strong><font size="2">try          <br />{           <br />    # Définition du crédential           <br />    $credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $login,$pwd -ErrorAction &laquo;&nbsp;silentlycontinue&nbsp;&raquo;; </font></strong></p>
<p><strong><font size="2">    # Protocol Canaux nommés à désactiver          <br />    $protocol = Get-WmiObject -computername $computername -credential $credential -namespace &laquo;&nbsp;root\Microsoft\SqlServer\ComputerManagement10&Prime; `           <br />                              -class ServerNetworkProtocol `           <br />                              -filter &laquo;&nbsp;ProtocolName=&rsquo;np&rsquo; and InstanceName=&rsquo;MSSQLSERVER'&nbsp;&raquo; `           <br />                              -ErrorAction &laquo;&nbsp;silentlycontinue&nbsp;&raquo;;           <br />    $protocol.SetDisable(); </font></strong></p>
<p><strong><font size="2">    # Protocol TCP à activer          <br />    $protocol = Get-WmiObject -computername $computername -credential $credential -namespace &laquo;&nbsp;root\Microsoft\SqlServer\ComputerManagement10&Prime; `           <br />                              -class ServerNetworkProtocol `           <br />                              -filter &laquo;&nbsp;ProtocolName=&rsquo;tcp&rsquo; and InstanceName=&rsquo;MSSQLSERVER'&nbsp;&raquo;;           <br />    $protocol.SetEnable(); </font></strong></p>
<p><font size="2"><strong>    # Redémarrage service SQL          <br />    $sqlservice = Get-WmiObject -computername $computername -credential $credential -namespace &laquo;&nbsp;root\Microsoft\SqlServer\ComputerManagement10&Prime; `           <br />                                -class SqlService `           <br />                                -filter &laquo;&nbsp;ServiceName=&rsquo;MSSQLSERVER'&nbsp;&raquo; `           <br />                                -ErrorAction &laquo;&nbsp;silentlycontinue&nbsp;&raquo;;           <br />    $sqlservice.StopService();           <br />    $sqlservice.StartService();           <br />}           <br />catch           <br />{           <br />    &laquo;&nbsp;Une erreur est survenue lors de la mise à jour des protocoles :&nbsp;&raquo;;           <br />    &laquo;&nbsp;Détail de l&rsquo;erreur :&nbsp;&raquo;           <br />    $err = $Error[0];           <br />    $err | Format-List *;           <br />}</strong> </font></p>
</blockquote>
<p><font size="2">Bonne activation de protocole !!</font></p>
<p><font size="2">David BARBARIN (Mikedavem)      <br />Elève ingénieur CNAM</font></p>
<p><font size="2"></font></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
