DSCResources/MSFT_xSCSPFServerSetup/MSFT_xSCSPFServerSetup.psm1
function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [ValidateSet("Present","Absent")] [System.String] $Ensure, [parameter(Mandatory = $true)] [System.String] $SourcePath, [System.String] $SourceFolder = "\SystemCenter2012R2\Orchestrator", [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [System.String] $SendCEIPReports = "False", [System.String] $UseMicrosoftUpdate = "False", [System.Boolean] $SpecifyCertificate = $false, [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter(Mandatory=$true)] [System.String] $DatabaseServer, [System.UInt16] $DatabasePortNumber, [System.String] $DatabaseName = "SCSPFDB", [System.UInt16] $WebSitePortNumber = 8090, [System.Management.Automation.PSCredential] $SCVMM, [System.Management.Automation.PSCredential] $SCAdmin = $SCVMM, [System.Management.Automation.PSCredential] $SCProvider = $SCVMM, [System.Management.Automation.PSCredential] $SCUsage = $SCVMM, [System.String] $VMMSecurityGroupUsers, [System.String] $AdminSecurityGroupUsers, [System.String] $ProviderSecurityGroupUsers, [System.String] $UsageSecurityGroupUsers ) Import-Module $PSScriptRoot\..\..\xPDT.psm1 $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SPF\setup.exe" $Path = ResolvePath $Path $Version = (Get-Item -Path $Path).VersionInfo.ProductVersion switch($Version) { "7.2.1902.0" { $IdentifyingNumber = "{69344E86-7183-4384-A230-499E9914BE14}" } "7.2.5017.0" { $IdentifyingNumber = "{69344E86-7183-4384-A230-499E9914BE14}" } Default { throw "Unknown version of Service Provider Foundation!" } } if(Get-WmiObject -Class Win32_Product | Where-Object {$_.IdentifyingNumber -eq $IdentifyingNumber}) { $DatabaseServer = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation" -Name "DatabaseServer").DatabaseServer $DatabasePort = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation" -Name "DatabasePort").DatabasePort if($DatabasePort -eq -1) { $DatabasePortNumber = 0 } else { $DatabasePortNumber = $DatabasePort } $DatabaseName = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation" -Name "DatabaseName").DatabaseName $WebSitePortNumber = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation" -Name "PortNumber").PortNumber $SCVMMUsername = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\VMM" -Name "AppPoolDomain").AppPoolDomain + "\" + (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\VMM" -Name "AppPoolUserName").AppPoolUserName $SCAdminUsername = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Admin" -Name "AppPoolDomain").AppPoolDomain + "\" + (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Admin" -Name "AppPoolUserName").AppPoolUserName $SCProviderUsername = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Provider" -Name "AppPoolDomain").AppPoolDomain + "\" + (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Provider" -Name "AppPoolUserName").AppPoolUserName $SCUsageUsername = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Usage" -Name "AppPoolDomain").AppPoolDomain + "\" + (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Provider Foundation\Usage" -Name "AppPoolUserName").AppPoolUserName $SPFGroups = @("VMM","Admin","Provider","Usage") foreach($SPFGroup in $SPFGroups) { Set-Variable -Name ($SPFGroup + "SecurityGroupUsers") -Value @() $Group = "SPF_$SPFGroup" $ADSIGroup = [ADSI]("WinNT://localhost/$Group,group") foreach($GroupMember in $ADSIGroup.Members()) { $AdsPath = $GroupMember.GetType().InvokeMember('Adspath', 'GetProperty', $Null, $GroupMember, $Null) $A = $AdsPath.split('/',[StringSplitOptions]::RemoveEmptyEntries) $Name = $A[2] $Domain = $A[1] if(($Domain + "\" + $Name) -ne (Get-Variable -Name ("SC" + $SPFGroup)).Value.Username) { Set-Variable -Name ($SPFGroup + "SecurityGroupUsers") -Value ((Get-Variable -Name ($SPFGroup + "SecurityGroupUsers")).Value + @(($Domain + "\" + $Name))) } } } $returnValue = @{ Ensure = "Present" SourcePath = $SourcePath SourceFolder = $SourceFolder DatabaseServer = $DatabaseServer DatabasePortNumber = $DatabasePortNumber DatabaseName = $DatabaseName WebSitePortNumber = $WebSitePortNumber SCVMMUsername = $SCVMMUsername SCAdminUsername = $SCAdminUsername SCProviderUsername = $SCProviderUsername SCUsageUsername = $SCUsageUsername VMMSecurityGroupUsers = $VMMSecurityGroupUsers AdminSecurityGroupUsers = $AdminSecurityGroupUsers ProviderSecurityGroupUsers = $ProviderSecurityGroupUsers UsageSecurityGroupUsers = $UsageSecurityGroupUsers } } else { $returnValue = @{ Ensure = "Absent" SourcePath = $SourcePath SourceFolder = $SourceFolder } } $returnValue } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [ValidateSet("Present","Absent")] [System.String] $Ensure, [parameter(Mandatory = $true)] [System.String] $SourcePath, [System.String] $SourceFolder = "\SystemCenter2012R2\Orchestrator", [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [System.String] $SendCEIPReports = "False", [System.String] $UseMicrosoftUpdate = "False", [System.Boolean] $SpecifyCertificate = $false, [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter(Mandatory=$true)] [System.String] $DatabaseServer, [System.UInt16] $DatabasePortNumber, [System.String] $DatabaseName = "SCSPFDB", [System.UInt16] $WebSitePortNumber = 8090, [System.Management.Automation.PSCredential] $SCVMM, [System.Management.Automation.PSCredential] $SCAdmin = $SCVMM, [System.Management.Automation.PSCredential] $SCProvider = $SCVMM, [System.Management.Automation.PSCredential] $SCUsage = $SCVMM, [System.String] $VMMSecurityGroupUsers, [System.String] $AdminSecurityGroupUsers, [System.String] $ProviderSecurityGroupUsers, [System.String] $UsageSecurityGroupUsers ) Import-Module $PSScriptRoot\..\..\xPDT.psm1 $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "\SPF\setup.exe" $Path = ResolvePath $Path $Version = (Get-Item -Path $Path).VersionInfo.ProductVersion Write-Verbose "Path: $Path" switch($Version) { "7.2.1902.0" { $IdentifyingNumber = "{69344E86-7183-4384-A230-499E9914BE14}" } "7.2.5017.0" { $IdentifyingNumber = "{69344E86-7183-4384-A230-499E9914BE14}" } Default { throw "Unknown version of Service Provider Foundation!" } } switch($Ensure) { "Present" { # Set defaults, if they couldn't be set in param due to null configdata input if($WebSitePortNumber -eq 0) { $WebSitePortNumber = 8090 } if($SendCEIPReports -ne "True") { $SendCEIPReports = "False" } if($UseMicrosoftUpdate -ne "True") { $UseMicrosoftUpdate = "False" } # Create install arguments $TempFile = [IO.Path]::GetTempFileName() $Arguments = "-Silent $TempFile" $AnswerFile = @() $AnswerFileVars = @( "SendCEIPReports", "UseMicrosoftUpdate", "DatabaseServer", "DatabasePortNumber", "DatabaseName", "WebSitePortNumber", "SpecifyCertificate" ) # If SpecifyCertificate = True, get serial number if($SpecifyCertificate) { $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"}) } $CertificateSerialNumber = $Certificates[0].SerialNumber $AnswerFileVars += @("CertificateSerialNumber") } foreach($AnswerFileVar in $AnswerFileVars) { if(!([String]::IsNullOrEmpty((Get-Variable -Name $AnswerFileVar).Value)) -and ((Get-Variable -Name $AnswerFileVar).Value -ne 0)) { $AnswerFile += "-$AnswerFileVar " + (Get-Variable -Name $AnswerFileVar).Value } } $AccountVars = @("SCVMM","SCAdmin","SCProvider","SCUsage") foreach($AccountVar in $AccountVars) { if($PSBoundParameters.ContainsKey("SCVMM") -or $PSBoundParameters.ContainsKey("$AccountVar")) { $AnswerFile += "-$AccountVar`NetworkServiceSelected False" $AnswerFile += "-$AccountVar`UserName " + (Get-Variable -Name $AccountVar).Value.GetNetworkCredential().UserName $AnswerFile += "-$AccountVar`Password " + (Get-Variable -Name $AccountVar).Value.GetNetworkCredential().Password $AnswerFile += "-$AccountVar`Domain " + (Get-Variable -Name $AccountVar).Value.GetNetworkCredential().Domain $AnswerFile += "-" + $AccountVar.Substring(2) + "SecurityGroupUsers " + (Get-Variable -Name $AccountVar).Value.UserName } else { $AnswerFile += "-$AccountVar`NetworkServiceSelected True" } } Write-Verbose "AnswerFile: $TempFile" foreach($Line in $AnswerFile) { Add-Content -Path $TempFile -Value $Line -Encoding Ascii # Replace sensitive values for verbose output $LogLine = $Line if($LogLine.Contains("Password")) { $LogLine = $LogLine.Split(" ")[0] + " ********" } Write-Verbose $LogLine } } "Absent" { # Create uninstall arguments $Arguments = "-Silent -Uninstall" } } Write-Verbose "Arguments: $Arguments" $Process = StartWin32Process -Path $Path -Arguments $Arguments -Credential $SetupCredential Write-Verbose $Process WaitForWin32ProcessEnd -Path $Path -Arguments $Arguments -Credential $SetupCredential # Add admins to groups if(($Ensure -eq "Present") -and (Get-WmiObject -Class Win32_Product | Where-Object {$_.IdentifyingNumber -eq "$IdentifyingNumber"})) { $SPFGroups = @("VMM","Admin","Provider","Usage") foreach($SPFGroup in $SPFGroups) { if($PSBoundParameters.ContainsKey("$SPFGroup`SecurityGroupUsers")) { $Group = "SPF_$SPFGroup" $ADSIGroup = [ADSI]("WinNT://localhost/$Group,group") foreach($User in (Get-Variable -Name "$SPFGroup`SecurityGroupUsers").Value.Split(";")) { $IsGroupMember = $false foreach($GroupMember in $ADSIGroup.Members()) { if(!$IsGroupMember) { $AdsPath = $GroupMember.GetType().InvokeMember('Adspath', 'GetProperty', $Null, $GroupMember, $Null) $A = $AdsPath.split('/',[StringSplitOptions]::RemoveEmptyEntries) $Name = $A[2] $Domain = $A[1] if(($Domain -eq $User.Split('\')[0]) -and ($Name -eq $User.Split('\')[1])) { $IsGroupMember = $true } } } if(!$IsGroupMember) { $ADSIUser = "WinNT://" + $User.Split("\")[0] + "/" + $User.Split("\")[1] $ADSIGroup.Add($ADSIUser) } } } } } # Clean up if(Test-Path -Path $TempFile) { Remove-Item -Path $TempFile } if((Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue) -ne $null) { $global:DSCMachineStatus = 1 } else { 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, [parameter(Mandatory = $true)] [System.String] $SourcePath, [System.String] $SourceFolder = "\SystemCenter2012R2\Orchestrator", [parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $SetupCredential, [System.String] $SendCEIPReports = "False", [System.String] $UseMicrosoftUpdate = "False", [System.Boolean] $SpecifyCertificate = $false, [System.String] $CertificateName = ($env:COMPUTERNAME + "." + (Get-WmiObject -Class Win32_ComputerSystem).Domain), [Parameter(Mandatory=$true)] [System.String] $DatabaseServer, [System.UInt16] $DatabasePortNumber, [System.String] $DatabaseName = "SCSPFDB", [System.UInt16] $WebSitePortNumber = 8090, [System.Management.Automation.PSCredential] $SCVMM, [System.Management.Automation.PSCredential] $SCAdmin = $SCVMM, [System.Management.Automation.PSCredential] $SCProvider = $SCVMM, [System.Management.Automation.PSCredential] $SCUsage = $SCVMM, [System.String] $VMMSecurityGroupUsers, [System.String] $AdminSecurityGroupUsers, [System.String] $ProviderSecurityGroupUsers, [System.String] $UsageSecurityGroupUsers ) $result = ((Get-TargetResource @PSBoundParameters).Ensure -eq $Ensure) $result } Export-ModuleMember -Function *-TargetResource |