DSCResources/MSFT_WebConfigConnectionString/MSFT_WebConfigConnectionString.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [String]$WebSite, [parameter(Mandatory = $true)] [String]$Name, [parameter(Mandatory = $true)] [String]$ConnectionString ) # Normalized path for IIS: drive $IISPath = "IIS:\Sites\$WebSite" Assert-Input -PSPath $IISPath # Filter for the given name $filter = "connectionStrings/add[@Name='$Name']" $connectionElement = Get-WebConfigurationProperty -PSPath $IISPath -Filter $filter -Name * [ordered]@{ Ensure = if($connectionElement){'Present'}else{'Absent'} WebSite = $WebSite Name = $connectionElement.Name ConnectionString = $connectionElement.ConnectionString ProviderName = $connectionElement.ProviderName } } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [String]$WebSite, [parameter(Mandatory = $true)] [String]$Name, [parameter(Mandatory = $true)] [String]$ConnectionString, [String]$ProviderName = 'System.Data.SqlClient', [ValidateSet('Present', 'Absent')] [string]$Ensure = 'Present' ) # Normalized path for IIS: drive $IISPath = "IIS:\Sites\$WebSite" Assert-Input -PSPath $IISPath Assert-Property -PSPath $IISPath -Name $Name -Apply ` -ConnectionString $ConnectionString -ProviderName $ProviderName } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [String]$WebSite, [parameter(Mandatory = $true)] [String]$Name, [parameter(Mandatory = $true)] [String]$ConnectionString, [String]$ProviderName = 'System.Data.SqlClient', [ValidateSet('Present', 'Absent')] [string]$Ensure = 'Present' ) # Normalized path for IIS: drive $IISPath = "IIS:\Sites\$WebSite" Assert-Input -PSPath $IISPath Assert-Property -PSPath $IISPath -Name $Name ` -ConnectionString $ConnectionString -ProviderName $ProviderName } #region Helper Function # Internal function to throw terminating error with specified errroCategory, errorId and errorMessage function New-TerminatingError { param ( [Parameter(Mandatory)] [String]$errorId, [Parameter(Mandatory)] [String]$errorMessage, [Parameter(Mandatory)] [System.Management.Automation.ErrorCategory]$errorCategory ) $exception = New-Object System.InvalidOperationException $errorMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null throw $errorRecord } function Assert-Input { param ( [parameter(Mandatory = $true)] [String]$PSPath ) # Find Website name from the PSPath of IIS drive $WebSite = $($PSPath.Split('\')[-1]) # Check if WebAdministration module is present for IIS cmdlets if(!(Get-Module -ListAvailable -Name WebAdministration)) { $errorString = 'Please ensure that IIS (Web-Server) role is installed with its PowerShell module' New-TerminatingError -errorId 'MissingWebAdministrationModule' -errorMessage $errorString ` -errorCategory InvalidOperation } Import-Module WebAdministration -Verbose:$false # Check website exists under IIS drive if(!(dir $PSPath -ErrorAction SilentlyContinue)) { $errorString = "There is no website $WebSite" New-TerminatingError -errorId 'MissingWebSite' -errorMessage $errorString ` -errorCategory InvalidOperation } # Check if the folder conatins web.config file if(! ((Get-WebConfigFile -PSPath $PSPath).Name -eq 'web.config') ) { $errorString = "Website $WebSite is missing web.config file" New-TerminatingError -errorId 'MissingWebConfigFile' -errorMessage $errorString ` -errorCategory InvalidOperation } } function Assert-Property { param ( [parameter(Mandatory = $true)] [String]$PSPath, [parameter(Mandatory = $true)] [String]$Name, [parameter(Mandatory = $true)] [String]$ConnectionString, [parameter(Mandatory = $true)] [String]$ProviderName, [Switch]$Apply #[Microsoft.IIs.PowerShell.Framework.ConfigurationElement] ) # Filter for the given name $filter = "connectionStrings/add[@Name='$Name']" Write-Verbose -Message "Checking connectionString element with Name='$Name' in web.config for $PSPath ..." $connectionElement = Get-WebConfigurationProperty -PSPath $PSPath -Filter $filter -Name * # If connectionString element is present if($connectionElement) { Write-Verbose -Message "Found connectionStrings element with Name='$Name' in web.config" # Validate various attributes, if the connectionStrings element should be present if($Ensure -eq 'Present') { #Check for connectiongstring attribute Write-Verbose -Message "Checking connectionString attribute for Name='$Name' ..." if($connectionElement.ConnectionString -ne $ConnectionString) { Write-Verbose -Message "connectionString attribute for Name='$Name' is not in desired state" Write-Debug -Message "connectionString expected $ConnectionString, but actual is $($connectionElement.ConnectionString)" if($Apply) { Set-WebConfigurationProperty -PSPath $PSPath -Filter $filter -Name 'ConnectionString' -Value $ConnectionString Write-Verbose -Message "connectionString attribute for Name='$Name' is now in desired state" Write-Debug -Message "connectionString is set to $($connectionElement.ConnectionString)" } else { return $false } } else { Write-Verbose -Message "connectionString attribute for Name='$Name' is in desired state" } #Check for providerName attribute Write-Verbose -Message "Checking providerName attribute for Name='$Name' ..." if($connectionElement.providerName -ne $ProviderName) { Write-Verbose -Message "providerName attribute for Name='$Name' is not in desired state. Expected $ProviderName, actual $($connectionElement.ProviderName)" if($Apply) { Set-WebConfigurationProperty -PSPath $PSPath -Filter $filter -Name 'ProviderName' -Value $ProviderName Write-Verbose -Message "providerName attribute for Name='$Name' is now in desired state" } else { return $false } } else { Write-Verbose -Message "providerName attribute for Name='$Name' is in desired state" } # If all the attributes are correct, return true for Test-TR function if(! $Apply){return $true} } # The element should not be present else { if($Apply) { Clear-WebConfiguration -PSPath $PSPath -Filter $filter } else { return $false } } } # If connectionString element is absent else { Write-Verbose -Message "connectionString element with Name='$Name' is not present in web.config" # If connectionStrings element should be present, add one if($Ensure -eq 'Present') { if($Apply) { # Element to add $item = @{Name=$Name;ConnectionString=$ConnectionString;ProviderName=$ProviderName} Write-Verbose -Message 'Adding a connectionString element in the web.config ...' Add-WebConfigurationProperty -PSPath $PSPath -Filter 'ConnectionStrings' -Name . -Value $item Write-Verbose -Message 'connectionString element successfully added to the web.config' } else { return $false } } else { # If connectionStrings element should be absent, return true for Test-TR function if(! $Apply){return $true} } } } #endregion Export-ModuleMember -Function *-TargetResource |