DSCResources/MSFT_xSCSMAWebServiceServerSetup/MSFT_xSCSMAWebServiceServerSetup.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter(Mandatory = $true)] [System.String] $SourcePath, [Parameter()] [System.String] $SourceFolder = '\SystemCenter2012R2\Orchestrator', [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [Parameter(Mandatory = $true)] [System.Boolean] $FirstWebServiceServer, [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $ApPool, [Parameter()] [System.String] $AdminGroupMembers, [Parameter(Mandatory = $true)] [System.String] $SqlServer, [Parameter(Mandatory = $true)] [System.String] $SqlInstance, [Parameter()] [System.String] $SqlDatabase = 'SMA', [Parameter()] [System.String] $SiteName = 'SMA', [Parameter()] [System.UInt16] $WebServicePort = 9090, [Parameter()] [System.String] $InstallFolder, [Parameter()] [System.String] $UseSSL = 'Yes', [Parameter()] [System.String] $SpecifyCertificate = 'No', [Parameter()] [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter()] [System.String] $ETWManifest = 'Yes', [Parameter()] [System.String] $SendTelemetryReports = 'No', [Parameter()] [System.String] $MSUpdate = 'No', [Parameter()] [System.String] $ProductKey, [Parameter()] [System.String[]] $RunbookWorkerServers ) Import-Module $PSScriptRoot\..\..\xPDT.psm1 $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SMA\WebServiceSetup.exe" $Path = ResolvePath $Path $Version = (Get-Item -Path $Path).VersionInfo.ProductVersion Write-Verbose -Message "Checking for version: $Version" switch($Version) { "7.2.1563.0" { # System Center 2012 R2 $IdentifyingNumber = "{4B76B636-AE9A-47D5-A246-E02909D97CF2}" } "7.3.345.0" { # System Center 2016 $IdentifyingNumber = "{4B76B636-AE9A-47D5-A246-E02909D97CF2}" } Default { throw "Unknown version of Service Management Automation!" } } if($null -ne (Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$IdentifyingNumber -ErrorAction SilentlyContinue)) { $SqlServer = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "DatabaseServerName").DatabaseServerName Write-Verbose -Message "Get-TargetResource: Registry content DB: $SqlServer" $SqlInstance = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "DatabaseServerInstance").DatabaseServerInstance if([String]::IsNullOrEmpty($SqlInstance)) { $SqlInstance = "MSSQLSERVER" } Write-Verbose -Message "Get-TargetResource: Registry content DB Instance: $SqlInstance" $SqlDatabase = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "DatabaseName").DatabaseName Write-Verbose -Message "Get-TargetResource: Registry content DB name: $SqlDatabase" $InstallFolder = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "InstallationFolder").InstallationFolder Write-Verbose -Message "Get-TargetResource: Registry install folder: $InstallFolder" $SiteName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "IisSiteName").IisSiteName Write-Verbose -Message "Get-TargetResource: Registry site name: $SiteName" $ApPoolUsername = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "IisAppPoolAccount").IisAppPoolAccount Write-Verbose -Message "Get-TargetResource: Registry app pool user: $ApPoolUsername" $AdminGroupMembers = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ServiceManagementAutomation\WebService" -Name "IisAuthorizationAdminGroupMembers").IisAuthorizationAdminGroupMembers Write-Verbose -Message "Get-TargetResource: Registry admin group members: $AdminGroupMembers" if(!(Get-Module -Name Microsoft.SystemCenter.ServiceManagementAutomation)) { Import-Module -Name Microsoft.SystemCenter.ServiceManagementAutomation } # In order to prevent a breaking change, we fall back to the default WSE # if the function call to $CertificateName does not work try { $RunbookWorkerServers = (Get-SmaRunbookWorkerDeployment -WebServiceEndpoint "https://$CertificateName" -Port $WebServicePort).ComputerName } catch { $RunbookWorkerServers = (Get-SmaRunbookWorkerDeployment -WebServiceEndpoint 'https://localhost' -Port $WebServicePort).ComputerName } $returnValue = @{ Ensure = "Present" SourcePath = $SourcePath SourceFolder = $SourceFolder ApPool = $ApPoolUsername AdminGroupMembers = $AdminGroupMembers SqlServer = $SqlServer SqlInstance = $SqlInstance SqlDatabase = $SqlDatabase SiteName = $SiteName InstallFolder = $InstallFolder SendTelemetryReports = $SendTelemetryReports RunbookWorkerServers = $RunbookWorkerServers } } else { $returnValue = @{ Ensure = "Absent" SourcePath = $SourcePath SourceFolder = $SourceFolder ServiceUsername = $null SqlServer = $null SqlInstance = $null SqlDatabase = $null InstallFolder = $null SendTelemetryReports = $null RunbookWorkerServers = $null } } $returnValue } function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter(Mandatory = $true)] [System.String] $SourcePath, [Parameter()] [System.String] $SourceFolder = '\SystemCenter2012R2\Orchestrator', [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [Parameter(Mandatory = $true)] [System.Boolean] $FirstWebServiceServer, [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $ApPool, [Parameter()] [System.String] $AdminGroupMembers, [Parameter(Mandatory = $true)] [System.String] $SqlServer, [Parameter(Mandatory = $true)] [System.String] $SqlInstance, [Parameter()] [System.String] $SqlDatabase = 'SMA', [Parameter()] [System.String] $SiteName = 'SMA', [Parameter()] [System.UInt16] $WebServicePort = 9090, [Parameter()] [System.String] $InstallFolder, [Parameter()] [System.String] $UseSSL = 'Yes', [Parameter()] [System.String] $SpecifyCertificate = 'No', [Parameter()] [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter()] [System.String] $ETWManifest = 'Yes', [Parameter()] [System.String] $SendTelemetryReports = 'No', [Parameter()] [System.String] $MSUpdate = 'No', [Parameter()] [System.String] $ProductKey, [Parameter()] [System.String[]] $RunbookWorkerServers, [System.String] $LogMsiInstall = $false, [System.String] $MsiLogPath = $env:LOCALAPPDATA + "\SystemCenter2016\SMA", [System.String] $MsiLogName = "SMAinstall.log" ) Import-Module $PSScriptRoot\..\..\xPDT.psm1 $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SMA\WebServiceSetup.exe" $Path = ResolvePath $Path $Version = (Get-Item -Path $Path).VersionInfo.ProductVersion Write-Verbose -Message "Checking for version: $Version" switch($Version) { "7.2.1563.0" { # System Center 2012 R2 $IdentifyingNumber = "{4B76B636-AE9A-47D5-A246-E02909D97CF2}" $SCVersion = "System Center 2012 R2" $SendCEIPReports = $SendTelemetryReports } "7.3.345.0" { # System Center 2016 $IdentifyingNumber = "{4B76B636-AE9A-47D5-A246-E02909D97CF2}" $SCVersion = "System Center 2016" } Default { throw "Unknown version of Service Management Automation!" } } $Path = "$env:windir\system32\msiexec.exe" $Path = ResolvePath $Path switch($Ensure) { "Present" { # Set defaults, if they couldn't be set in param due to null configdata input if($WebServicePort -eq 0) { $WebServicePort = 9090 } foreach($ArgumentVar in ('UseSSL','SpecifyCertificate','ETWManifest','SendCEIPReports','SendTelemetryReports','MSUpdate')) { if((Get-Variable -Name $ArgumentVar).Value -ne 'Yes') { Set-Variable -Name $ArgumentVar -Value 'No' } } if([String]::IsNullOrEmpty($AdminGroupMembers)) { $AdminGroupMembers = $ApPool.UserName } else { $AdminGroupMembers = "$AdminGroupMembers,$($ApPool.UserName)" } $MSIPath = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SMA\WebServiceInstaller.msi" $MSIPath = ResolvePath $MSIPath Write-Verbose "MSIPath: $MSIPath" # Create install arguments $Arguments = "/q /i $MSIPath" if(($PSVersionTable.PSVersion.Major -eq 5) -and ($SCVersion -eq "System Center 2012 R2")) { $MSTPath = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SMA\WMF5WebService.mst" $MSTPath = ResolvePath $MSTPath Write-Verbose "MSTPath: $MSTPath" $Arguments += " TRANSFORMS=$MSTPath" } $Arguments += " ALLUSERS=2 DatabaseAuthentication=Windows" $ArgumentVars = @( "AdminGroupMembers", "SqlServer", "SqlDatabase", "SiteName", "WebServicePort", "UseSSL", "SpecifyCertificate", "InstallFolder", "ETWManifest" "MSUpdate", "ProductKey" ) if($SCVersion -eq "System Center 2012 R2") { $ArgumentVars += @( "SendCEIPReports" ) } else { $ArgumentVars += @( "SendTelemetryReports" ) } if($SQLInstance -ne "MSSQLSERVER") { $ArgumentVars += @( "SqlInstance" ) } # If SpecifyCertificate = Yes, get serial number if($SpecifyCertificate -eq "Yes") { $Certificates = @(Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object {($_.Subject -eq "CN=$CertificateName") -and ($_.Issuer -ne "CN=$CertificateName")} | Where-Object {$_.EnhancedKeyUsageList.ObjectId -eq "1.3.6.1.5.5.7.3.1"}) if($Certificates.Count -eq 0) { $Certificates = @(Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object {$_.Subject -eq "CN=$CertificateName"} | Where-Object {$_.EnhancedKeyUsageList.ObjectId -eq "1.3.6.1.5.5.7.3.1"}) } if($Certificates.Count -eq 0) { $null = New-SelfSignedCertificate -DnsName $CertificateName -CertStoreLocation "Cert:\LocalMachine\My" $Certificates = @(Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object {$_.Subject -eq "CN=$CertificateName"} | Where-Object {$_.EnhancedKeyUsageList.ObjectId -eq "1.3.6.1.5.5.7.3.1"}) } $CertificateSerial = $Certificates[0].SerialNumber $ArgumentVars += @("CertificateSerial") } if($FirstWebServiceServer) { $Arguments += " CreateDatabase=Yes" } else { $Arguments += " CreateDatabase=No" } foreach($ArgumentVar in $ArgumentVars) { if(!([String]::IsNullOrEmpty((Get-Variable -Name $ArgumentVar).Value))) { $Arguments += " $ArgumentVar=`"" + [Environment]::ExpandEnvironmentVariables((Get-Variable -Name $ArgumentVar).Value) + "`"" } } $AccountVars = @("ApPool") foreach($AccountVar in $AccountVars) { $Arguments += " $AccountVar`Account=`"" + (Get-Variable -Name $AccountVar).Value.UserName + "`"" $Arguments += " $AccountVar`Password=`"" + (Get-Variable -Name $AccountVar).Value.GetNetworkCredential().Password + "`"" } # Check if logging is wanted if($LogMsiInstall) { # Create Path if not exist $logPathName = Join-Path -Path $MsiLogPath -ChildPath $MSIlogName Write-Verbose "MSI install log location: $logPathName" if(!(Test-Path -Path $MsiLogPath)) { New-Item -ItemType Directory -Force -Path $MsiLogPath } else { if(Test-Path -Path $logPathName) { # Remove logfile if exsists Remove-Item -Path $logPathName -Force } } Write-Verbose -Message "MSI logfile: $logPathName" $Arguments += " /L*V ""$logPathName""" } # Replace sensitive values for verbose output $Log = $Arguments $LogVars = @("ApPool") foreach($LogVar in $LogVars) { if((Get-Variable -Name $LogVar).Value -ne "") { $Log = $Log.Replace((Get-Variable -Name $LogVar).Value.GetNetworkCredential().Password,"********") } } } "Absent" { $Arguments = "/q /x $IdentifyingNumber" $Log = $Arguments } } Write-Verbose "Path: $Path" Write-Verbose "Arguments: $Log" $Process = StartWin32Process -Path $Path -Arguments $Arguments -Credential $SetupCredential Write-Verbose $Process WaitForWin32ProcessEnd -Path $Path -Arguments $Arguments -Credential $SetupCredential # Additional first Web Service Server "Present" actions if(($Ensure -eq "Present") -and $FirstWebServiceServer -and ($null -ne (Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$IdentifyingNumber -ErrorAction SilentlyContinue))) { if(!(Get-Module -Name Microsoft.SystemCenter.ServiceManagementAutomation)) { Import-Module -Name Microsoft.SystemCenter.ServiceManagementAutomation $Workers = @() foreach($RunbookWorkerServer in $RunbookWorkerServers) { $Workers += $RunbookWorkerServer.Split(".")[0] } New-SmaRunbookWorkerDeployment -WebServiceEndpoint "https://$CertificateName" -Port $WebServicePort -ComputerName $Workers } } if((Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue) -ne $null) { $global:DSCMachineStatus = 1 } else { Write-Verbose -Message "Testing TargetResource" Write-Verbose -Message "Parameters: $($PSBoundParameters | Out-String)" if(!(Test-TargetResource @PSBoundParameters)) { throw "Set-TargetResouce failed" } } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [Parameter(Mandatory = $true)] [System.String] $SourcePath, [Parameter()] [System.String] $SourceFolder = '\SystemCenter2012R2\Orchestrator', [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [Parameter(Mandatory = $true)] [System.Boolean] $FirstWebServiceServer, [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $ApPool, [Parameter()] [System.String] $AdminGroupMembers, [Parameter(Mandatory = $true)] [System.String] $SqlServer, [Parameter(Mandatory = $true)] [System.String] $SqlInstance, [Parameter()] [System.String] $SqlDatabase = 'SMA', [Parameter()] [System.String]$SiteName = 'SMA', [Parameter()] [System.UInt16] $WebServicePort = 9090, [Parameter()] [System.String] $InstallFolder, [Parameter()] [System.String] $UseSSL = 'Yes', [Parameter()] [System.String] $SpecifyCertificate = 'No', [Parameter()] [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter()] [System.String] $ETWManifest = 'Yes', [Parameter()] [System.String] $SendTelemetryReports = 'No', [Parameter()] [System.String] $MSUpdate = 'No', [Parameter()] [System.String] $ProductKey, [Parameter()] [System.String[]] $RunbookWorkerServers, [System.String] $LogMsiInstall = $false, [System.String] $MsiLogPath = $env:LOCALAPPDATA + "\SystemCenter2016\SMA", [System.String] $MsiLogName = "SMAinstall.log" ) $result = ((Get-TargetResource @PSBoundParameters).Ensure -eq $Ensure) $result } Export-ModuleMember -Function *-TargetResource |