Modules/Common.psm1
function Get-CurrentMIM { [CmdletBinding()] $MIM = Get-Package | where {$_.Name -eq "Microsoft Identity Manager Service and Portal"} return $MIM } function Install-MimSvc { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $setupFiles, [Parameter(Mandatory = $true)] [string] $productId, [Parameter(Mandatory = $true)] [string] $sqlServerInstance, [Parameter(Mandatory = $true)] [string] $sqlServerDb, [Parameter(Mandatory = $true)] [pscredential] $mimSvcAccount, [Parameter(Mandatory = $true)] [pscredential] $emailSvcAccount, [Parameter(Mandatory = $false)] [string] $serviceServer = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [string] $syncServer = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [string] $syncServiceAccount, [Parameter(Mandatory = $false)] [string] $mailServer = "outlook.office365.com", [Parameter(Mandatory = $true)] [ValidateSet(0,1)] [int] $useExistingDatabase, [Parameter(Mandatory = $true)] [string] $serviceAddress ) Write-Verbose -Message "Starting MIM Service pre-reqs check." if(!(Test-Path $setupFiles)) { Write-Error "$setupFiles location is not found or not accessible please check and try again." break } Write-Verbose "Checking windows pre-reqs required for MIM Service." #Checking windows features Test-WinFPrereqs ################################################################## $mimSvcAccountD = $mimSvcAccount.UserName.Split("\") $mimSvcAccountName = $mimSvcAccountD[1] $mimSvcAccountDomain = $mimSvcAccountD[0] $mimSvcAccountPass = $mimSvcAccount.GetNetworkCredential().Password $logs = "$env:TMP\FimService.log" $emailAccount = $emailSvcAccount.UserName $emailAccountPass = $emailSvcAccount.GetNetworkCredential().Password $setupFiles = '"{0}"' -f $setupFiles $exitcodes = @(0, 3010, 1641) Write-Verbose "Merging data inputs" $Arguments = @( "/i" $setupFiles "ADDLOCAL=CommonServices" "ACCEPT_EULA=1" "SQLSERVER_SERVER=$sqlServerInstance" "SQLSERVER_DATABASE=$sqlServerDb" "EXISTINGDATABASE=$useExistingDatabase" "SERVICE_ACCOUNT_NAME=$mimSvcAccountName" "SERVICE_ACCOUNT_PASSWORD=$mimSvcAccountPass" "SERVICE_ACCOUNT_DOMAIN=$mimSvcAccountDomain" "SERVICE_ACCOUNT_EMAIL=$emailAccount" "SERVICE_ACCOUNT_EMAIL_PASSWORD=$emailAccountPass" "SERVICE_MANAGER_SERVER=$serviceServer" "SYNCHRONIZATION_SERVER=$syncServer" "SYNCHRONIZATION_SERVER_ACCOUNT=$syncServiceAccount" "MAIL_SERVER=$mailServer" "SERVICEADDRESS=$serviceAddress" "MAIL_SERVER_USE_SSL=1" "MAIL_SERVER_IS_EXCHANGE=1" "POLL_EXCHANGE_ENABLED=0" "MAIL_SERVER_IS_EXCHANGE_ONLINE=1" "SQMOPTINSETTING=0" "REBOOT=ReallySuppress" "/l*v $logs" "/qn" ) -join ' ' ####################################################################### try { #Checking user rights assignment Test-ServiceAccountRights -svcAccountName $mimSvcAccount.UserName -ErrorAction Stop Test-ServiceAccountRights -svcAccountName $syncServiceAccount -ErrorAction Stop $sqlCon = Test-SqlDb -SqlServerInstance $sqlServerInstance -SqlDbName $sqlServerDb if($sqlCon.Exists -and $useExistingDatabase -eq 1) { Write-Verbose "Database $sqlServerDb exists and will be used for this configuration" } elseif($sqlCon.Exists -and $useExistingDatabase -eq 0) { Write-Error "Database with name $sqlServerDb already exists. Either delete this DB or Change UseExistingDatabase to 1" break } elseif(!$sqlCon.Exists -and $useExistingDatabase -eq 0) { Write-Verbose "Creating database with name $sqlServerDb" } Write-Verbose "Starting MIM Service Installation" $run = Start-Process msiexec -ArgumentList $Arguments -Wait -PassThru -Verbose -Verb RunAs $ex = $run.ExitCode Start-Sleep -Seconds 10 if($exitcodes -ccontains $ex) { Write-Verbose "FimService installation completed." Write-Verbose "For detailed logs check file at $logs" } elseif($ex -eq 1618) { Write-Error "ERROR_INSTALL_ALREADY_RUNNING - Another MSI installation is running. Either wait for it to complete Or Stop msiexec process and Try again..." break } elseif($ex -eq 1619 -or $ex -eq 1620) { Write-Error "ERROR_INSTALL_PACKAGE_OPEN_FAILED - This installation package $setupFiles could not be opened. Verify that the package exists and is accessible." break } else { Write-Error "Fim Service installation has failed. Installation returned error $ex, refer to ` https://docs.microsoft.com/en-us/windows/desktop/msi/error-codes for more details on error codes" Write-Verbose "For detailed logs check file at $logs, if file doesnt exists please check events" break } } catch { $errorMessage = $_.Exception.Message $failedItems = $_.Exception.itemName Write-Error $errorMessage Write-Error $failedItems Write-Warning "For detailed logs check file at $logs" break } } function Update-MimSvc { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $SourceFile ) $SourceFile = '"{0}"' -f $SourceFile $exitcodes = @(0, 3010, 1641) $logs = "$env:TMP\MimServicePatch.log" $arguments = @( "/p" $SourceFile "/l*v" $logs "/qn" ) -join " " try { Get-VisualC -Verbose -ErrorAction Stop Write-Verbose "Stopping FimService..." Stop-Service -Name FIMService -Force -Verbose Write-Verbose "Starting installation of $SourceFile patch" $run = Start-Process msiexec -ArgumentList $arguments -Verb RunAs -Wait -PassThru -Verbose $ex = $run.ExitCode if($exitcodes -ccontains $ex) { Write-Verbose "FimService is successfully updated." Write-Verbose "For detailed logs check file at $logs" } elseif($ex -eq 1635 -or $ex -eq 1636) { Write-Error "ERROR_INSTALL_PACKAGE_OPEN_FAILED - This installation package $SourceFile could not be opened. Verify that the package exists and is accessible." break } else { Write-Error "Fim Service update installation has failed. Installation returned error $ex, refer to ` https://docs.microsoft.com/en-us/windows/desktop/msi/error-codes for more details on error codes" Write-Verbose "For detailed logs check file at $logs, if file doesnt exists please check events" break } } catch { $errorMessage = $_.Exception.Message $failedItems = $_.Exception.itemName Write-Error $errorMessage Write-Error $failedItems Write-Warning "For detailed logs check file at $logs" break } } function Test-WinFPrereqs { import-module ServerManager -Cmdlet Get-WindowsFeature $install = @() $requiredFeatures = @("Web-WebServer", "Net-Framework-Features", "rsat-ad-powershell", "Web-Mgmt-Tools", "Windows-Identity-Foundation", "Server-Media-Foundation", "Xps-Viewer" ) foreach($feature in $requiredFeatures) { $f = Get-WindowsFeature -Name $feature -Verbose if($f.Installed -ne $true) { $install += $f.Installed Write-Error "$feature is not installed. Please install first and try again." } else { $install += $f.Installed Write-Verbose "$feature is installed." } } if($install -contains $false) { Write-Error "One of pre-req is missing, please check and try again." break } Write-Verbose "Required windows features are installed." } function Test-ServiceAccountRights { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $svcAccountName ) Write-Verbose "Checking Log on as Service rights for $svcAccountName on server..." $tempPath = [System.IO.Path]::GetTempPath() $export = Join-Path -Path $tempPath -ChildPath "SeExport.inf" $sid = ((New-Object System.Security.Principal.NTAccount($svcAccountName)).Translate([System.Security.Principal.SecurityIdentifier])).Value $sid = "*"+$sid $ex = secedit /export /cfg $export $sids = (Select-String $export -Pattern "SeServiceLogonRight").Line $sids = $sids.Split(",") $sids = $sids.Split("=").Trim() if($sids -ccontains $sid) { Write-Verbose "$svcAccountName has Log on as Service rights." return $true } else { Write-Error "$svcAccountName is not granted Log on as Service rights on server." #break } } function Update-FimServiceReg { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string] $svcGmsaAccountName ) Write-Verbose "Updating FimService registry..." $FimService = Get-FimReg $regAccount = $FimService.GetValue("ObjectName") try { if($FimService) { Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\FimService" ` -Name "ObjectName" -Value $svcGmsaAccountName } } catch { throw $_.Exception.Message } } function Install-MIMPamWithGmsa { [CmdletBinding()] param( [parameter(Mandatory = $true)] [System.String] $SetupFiles, [parameter(Mandatory = $false)] [System.String] $SyncServer = $env:COMPUTERNAME, [parameter(Mandatory = $false)] [System.String] $ServiceServer = $env:COMPUTERNAME, [parameter(Mandatory = $true)] [System.String] $PAMCompGmsaAccount, [parameter(Mandatory = $true)] [System.String] $PAMMonGmsaAccount, [parameter(Mandatory = $true)] [System.String] $PAMWebPoolGmsaAccount, [parameter(Mandatory = $false)] [System.UInt16] $PAMRestApiPort = 8086, [Parameter(Mandatory = $true)] [pscredential] $emailSvcAccount, [parameter(Mandatory = $true)] [System.String] $ServiceAddress ) ########################################################################### #Building variables $FimServiceReg = Get-FimReg $sqlServerInstance = $FimServiceReg.GetValue("DatabaseServer") $sqlServerDb = $FimServiceReg.GetValue("DatabaseName") $emailAccount = $emailSvcAccount.UserName $emailAccountPass = $emailSvcAccount.GetNetworkCredential().Password $syncServiceAccount = $FimServiceReg.GetValue("SynchronizationAccount") $mailServer = "outlook.office365.com" $exitcodes = @(0, 3010, 1641) $MIMSvcGmsaAccount = $FimServiceReg.GetValue("ObjectName") $mimSvcAccountD = $MIMSvcGmsaAccount.Split("\") $mimSvcAccountName = $mimSvcAccountD[1] $mimSvcAccountDomain = $mimSvcAccountD[0] $pamCompAccount = $PAMCompGmsaAccount.Split("\") $pamCompAccountName = $pamCompAccount[1] $pamCompAccountDomain = $pamCompAccount[0] $pamMonAccount = $PAMMonGmsaAccount.Split("\") $pamMonAccountName = $pamMonAccount[1] $pamMonAccountDomain = $pamMonAccount[0] $pamWebPoolAcc = $PAMWebPoolGmsaAccount.Split("\") $pamWebPoolAccName = $pamWebPoolAcc[1] $PAMWebPoolAccDomain = $pamWebPoolAcc[0] $logs = "$env:TMP\MIMPAM_Install.log" ########################################################################### Write-Verbose -Message "Starting MIM PAM Services pre-reqs check." if(!(Test-Path $SetupFiles)) { Write-Error "$SetupFiles location is not found or not accessible please check and try again." break } $SetupFiles = '"{0}"' -f $SetupFiles Write-Verbose "Checking windows pre-reqs required for MIM PAM Services." #Checking windows features ########################## Test-WinFPrereqs $Arguments = @( "/i" $SetupFiles "ADDLOCAL=CommonServices,PAMServices" "ACCEPT_EULA=1" "USE_MANAGED_ACCOUNT_FOR_SERVICE=1" "SQLSERVER_SERVER=$sqlServerInstance" "SQLSERVER_DATABASE=$sqlServerDb" "EXISTINGDATABASE=1" "SERVICE_ACCOUNT_NAME=$mimSvcAccountName" "SERVICE_ACCOUNT_DOMAIN=$mimSvcAccountDomain" "SERVICE_ACCOUNT_EMAIL=$emailAccount" "SERVICE_ACCOUNT_EMAIL_PASSWORD=$emailAccountPass" "SERVICE_MANAGER_SERVER=$ServiceServer" "SYNCHRONIZATION_SERVER=$SyncServer" "SYNCHRONIZATION_SERVER_ACCOUNT=$syncServiceAccount" "MAIL_SERVER=$mailServer" "SERVICEADDRESS=$ServiceAddress" "POLL_EXCHANGE_ENABLED=0" "MAIL_SERVER_IS_EXCHANGE_ONLINE=1" "PAM_MONITORING_SERVICE_ACCOUNT_DOMAIN=$pamMonAccountDomain" "PAM_MONITORING_SERVICE_ACCOUNT_NAME=$pamMonAccountName" "PAM_COMPONENT_SERVICE_ACCOUNT_DOMAIN=$pamCompAccountDomain" "PAM_COMPONENT_SERVICE_ACCOUNT_NAME=$pamCompAccountName" "PAM_REST_API_APPPOOL_ACCOUNT_DOMAIN=$PAMWebPoolAccDomain" "PAM_REST_API_APPPOOL_ACCOUNT_NAME=$PAMWebPoolAccName" "MIMPAM_REST_API_PORT=$PAMRestApiPort" "SQMOPTINSETTING=0" "FIREWALL_CONF=1" "REBOOT=ReallySuppress" "/l*v $logs" "/qn" ) -join ' ' try { #Checking user rights assignment Write-Verbose "Checking SVCs accounts Log on as Service Rights on server.." Test-ServiceAccountRights -svcAccountName $PAMCompGmsaAccount -Verbose -ErrorAction Stop Test-ServiceAccountRights -svcAccountName $PAMMonGmsaAccount -Verbose -ErrorAction Stop Test-ServiceAccountRights -svcAccountName $PAMWebPoolGmsaAccount -Verbose -ErrorAction Stop Write-Verbose "Starting PAM Services Installation...." $run = Start-Process msiexec -ArgumentList $Arguments -Wait -PassThru -Verbose -Verb RunAs $ex = $run.ExitCode Start-Sleep -Seconds 10 if($exitcodes -ccontains $ex) { Write-Verbose "PAM Services installations is successful." Write-Verbose "For detailed logs check file at $logs" return @{ ExitCode = $ex } } elseif($ex -eq 1618) { Write-Error "ERROR_INSTALL_ALREADY_RUNNING - Another MSI installation is running. Either wait for it to complete Or Stop msiexec process and Try again..." break } elseif($ex -eq 1619 -or $ex -eq 1620) { Write-Error "ERROR_INSTALL_PACKAGE_OPEN_FAILED - This installation package $SetupFiles could not be opened. Verify that the package exists and is accessible." break } else { Write-Error "PAM Installation has failed. Installation returned error $ex, refer to ` https://docs.microsoft.com/en-us/windows/desktop/msi/error-codes for more details on error codes" Write-Verbose "For detailed logs check file at $logs, if file doesnt exists please check events" break } } catch { $errorMessage = $_.Exception.Message $failedItems = $_.Exception.itemName Write-Error $errorMessage Write-Error $failedItems Write-Warning "For detailed logs check file at $logs" break } } function Get-FimReg { $fimReg = Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\FimService" return $fimReg } function Switch-MimToGmsa { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $SetupFiles, [Parameter(Mandatory = $true)] [pscredential] $CurrentServiceAccount, [Parameter(Mandatory = $true)] [string] $MIMSvcGmsaAccount, [parameter(Mandatory = $false)] [System.String] $SyncServer = $env:COMPUTERNAME, [parameter(Mandatory = $false)] [System.String] $ServiceServer = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [pscredential] $emailSvcAccount, [parameter(Mandatory = $true)] [System.String] $ServiceAddress ) #========================================================================= #Creating variables $FimServiceReg = Get-FimReg $currentRegAccount = $FimServiceReg.GetValue("ObjectName") if($CurrentServiceAccount.UserName -ne $currentRegAccount) { Write-Error "Current Service Account provided doesnt match with the account linked to Fim service." break } $sqlServerInstance = $FimServiceReg.GetValue("DatabaseServer") $sqlServerDb = $FimServiceReg.GetValue("DatabaseName") $emailAccount = $emailSvcAccount.UserName $emailAccountPass = $emailSvcAccount.GetNetworkCredential().Password $syncServiceAccount = $FimServiceReg.GetValue("SynchronizationAccount") $mailServer = "outlook.office365.com" $useExistingDatabase = "1" $SetupFiles = '"{0}"' -f $SetupFiles $exitcodes = @(0, 3010, 1641) $mimSvcAccountD = $MIMSvcGmsaAccount.Split("\") $mimSvcAccountName = $mimSvcAccountD[1] $mimSvcAccountDomain = $mimSvcAccountD[0] $logs = "$env:TMP\MIMSvc_GmsaSwitch.log" #========================================================================== $Arguments = @( "/i" $SetupFiles "ADDLOCAL=CommonServices" "ACCEPT_EULA=1" "SQLSERVER_SERVER=$sqlServerInstance" "SQLSERVER_DATABASE=$sqlServerDb" "EXISTINGDATABASE=$useExistingDatabase" "SERVICE_ACCOUNT_NAME=$mimSvcAccountName" "SERVICE_ACCOUNT_DOMAIN=$mimSvcAccountDomain" "SERVICE_ACCOUNT_EMAIL=$emailAccount" "SERVICE_ACCOUNT_EMAIL_PASSWORD=$emailAccountPass" "SERVICE_MANAGER_SERVER=$ServiceServer" "SYNCHRONIZATION_SERVER=$SyncServer" "SYNCHRONIZATION_SERVER_ACCOUNT=$syncServiceAccount" "MAIL_SERVER=$mailServer" "SERVICEADDRESS=$ServiceAddress" "MAIL_SERVER_USE_SSL=1" "MAIL_SERVER_IS_EXCHANGE=1" "POLL_EXCHANGE_ENABLED=0" "MAIL_SERVER_IS_EXCHANGE_ONLINE=1" "USE_MANAGED_ACCOUNT_FOR_SERVICE=1" "SQMOPTINSETTING=0" "REBOOT=ReallySuppress" "/l*v $logs" "/qn" ) try { Write-Verbose "Starting MIM Service swtitch to GMSA.." Update-FimServiceReg -svcGmsaAccountName $MIMSvcGmsaAccount -Verbose -ErrorAction Stop Get-GmsaAccount -accountName $MIMSvcGmsaAccount -Verbose Test-ServiceAccountRights -svcAccountName $MIMSvcGmsaAccount -Verbose -ErrorAction Stop Write-Verbose "Changes are in progress..." $run = Start-Process msiexec -ArgumentList $Arguments -Wait -PassThru -Verbose -Verb RunAs $ex = $run.ExitCode Start-Sleep -Seconds 10 if($exitcodes -ccontains $ex) { Write-Warning "FimService able to switch to GMSA successfully, Reboot needed to complete installation." Write-Verbose "For detailed logs check file at $logs" return @{ ExitCode = $ex } } elseif($ex -eq 1618) { Write-Error "ERROR_INSTALL_ALREADY_RUNNING - Another MSI installation is running. Either wait for it to complete Or Stop msiexec process and Try again..." break } elseif($ex -eq 1619 -or $ex -eq 1620) { Write-Error "ERROR_INSTALL_PACKAGE_OPEN_FAILED - This installation package $SetupFiles could not be opened. Verify that the package exists and is accessible." break } else { Write-Warning "Fim Service unable to switch to GMSA. Installation returned error $ex, refer to ` https://docs.microsoft.com/en-us/windows/desktop/msi/error-codes for more details on error codes" Write-Warning "For detailed logs check file at $logs, if file doesnt exists please check events" Write-Verbose "Rolling back to previous service account" Switch-MimToNormalSvcAccount -SetupFiles $SetupFiles -NormalServiceAccount $CurrentServiceAccount ` -SyncServer $SyncServer -ServiceServer $ServiceServer -emailSvcAccount $emailSvcAccount -ServiceAddress $ServiceAddress ` -Verbose Write-Verbose "FIM Service unable to switch to GMSA. Rolled back to previous account.." } } catch { $errorMessage = $_.Exception.Message $failedItems = $_.Exception.itemName Write-Error $errorMessage Write-Error $failedItems Write-Warning "For detailed logs check file at $logs" break } } function Switch-MimToNormalSvcAccount { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $SetupFiles, [Parameter(Mandatory = $true)] [pscredential] $NormalServiceAccount, [parameter(Mandatory = $false)] [System.String] $SyncServer = $env:COMPUTERNAME, [parameter(Mandatory = $false)] [System.String] $ServiceServer = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [pscredential] $emailSvcAccount, [parameter(Mandatory = $true)] [System.String] $ServiceAddress ) #================================================================== #Building Variables $FimServiceReg = Get-FimReg $sqlServerInstance = $FimServiceReg.GetValue("DatabaseServer") $sqlServerDb = $FimServiceReg.GetValue("DatabaseName") $emailAccount = $emailSvcAccount.UserName $emailAccountPass = $emailSvcAccount.GetNetworkCredential().Password $syncServiceAccount = $FimServiceReg.GetValue("SynchronizationAccount") $mailServer = "outlook.office365.com" $useExistingDatabase = "1" $SetupFiles = '"{0}"' -f $SetupFiles $exitcodes = @(0, 3010, 1641) $mimSvcAccountD = $NormalServiceAccount.Username.Split("\") $mimSvcAccountName = $mimSvcAccountD[1] $mimSvcAccountDomain = $mimSvcAccountD[0] $mimSvcAccountPass = $NormalServiceAccount.GetNetworkCredential().Password $logs = "$env:TMP\MIMSvc_NormalAccountSwitch.log" $Arguments = @( "/i" $SetupFiles "ADDLOCAL=CommonServices" "ACCEPT_EULA=1" "SQLSERVER_SERVER=$sqlServerInstance" "SQLSERVER_DATABASE=$sqlServerDb" "EXISTINGDATABASE=$useExistingDatabase" "SERVICE_ACCOUNT_NAME=$mimSvcAccountName" "SERVICE_ACCOUNT_DOMAIN=$mimSvcAccountDomain" "SERVICE_ACCOUNT_PASSWORD=$mimSvcAccountPass" "SERVICE_ACCOUNT_EMAIL=$emailAccount" "SERVICE_ACCOUNT_EMAIL_PASSWORD=$emailAccountPass" "SERVICE_MANAGER_SERVER=$ServiceServer" "SYNCHRONIZATION_SERVER=$SyncServer" "SYNCHRONIZATION_SERVER_ACCOUNT=$syncServiceAccount" "MAIL_SERVER=$mailServer" "SERVICEADDRESS=$ServiceAddress" "MAIL_SERVER_USE_SSL=1" "MAIL_SERVER_IS_EXCHANGE=1" "POLL_EXCHANGE_ENABLED=0" "MAIL_SERVER_IS_EXCHANGE_ONLINE=1" "USE_MANAGED_ACCOUNT_FOR_SERVICE=0" "SQMOPTINSETTING=0" "REBOOT=ReallySuppress" "/l*v $logs" "/qn" ) #=================================================================== try { Write-Verbose "Switching to MIM Service to Normal Account.." Update-FimServiceReg -svcGmsaAccountName $NormalServiceAccount.UserName -Verbose -ErrorAction Stop Test-ServiceAccountRights -svcAccountName $NormalServiceAccount.UserName -Verbose -ErrorAction Stop Write-Verbose "Roll back in progress.." $run = Start-Process msiexec -ArgumentList $Arguments -Wait -PassThru -Verbose -Verb RunAs $ex = $run.ExitCode Start-Sleep -Seconds 10 if($exitcodes -ccontains $ex) { Write-Warning "FimService able to switch to Normal Account, Reboot needed to complete installation." Write-Verbose "For detailed logs check file at $logs" $global:DSCMachineStatus = 1 } elseif($ex -eq 1618) { Write-Error "ERROR_INSTALL_ALREADY_RUNNING - Another MSI installation is running. Either wait for it to complete Or Stop msiexec process and Try again..." break } elseif($ex -eq 1619 -or $ex -eq 1620) { Write-Error "ERROR_INSTALL_PACKAGE_OPEN_FAILED - This installation package $SetupFiles could not be opened. Verify that the package exists and is accessible." break } else { Write-Error "Fim Service unable to switch to Normal Account. Installation returned error $ex, refer to ` https://docs.microsoft.com/en-us/windows/desktop/msi/error-codes for more details on error codes" Write-Warning "For detailed logs check file at $logs, if file doesnt exists please check events" } } catch { $errorMessage = $_.Exception.Message $failedItems = $_.Exception.itemName Write-Error $errorMessage Write-Error $failedItems Write-Warning "For detailed logs check file at $logs" break } } function Get-GmsaAccount { param( [parameter(mandatory = $true)] [string] $accountName ) $accountN = $accountName.Split("\") if($accountN.Count -ne 2) { Write-Error "Provided account is not in Domain\UserName format.." break } $gmsaType = "ms-DS-Group-Managed-Service-Account" $accountN = $accountN[1] $accountDetails = ([adsisearcher]"(sAMAccountName=$accountN)").FindOne() $accountType = [string]($accountDetails.Properties.objectcategory) if($accountType -match $gmsaType) { Write-Verbose "$accountName is GMSA account.." return $true } else { Write-Verbose "$accountName is not of GMSA Type.." return $false } } function Get-CurrentAccount { $fimreg = Get-FimReg $AccountName = $fimreg.GetValue("ObjectName") $accountN = $AccountName.Split("\") if(Get-GmsaAccount -accountName $AccountName) { return $true } else { return $false } } function Get-VisualC { $vs = "Microsoft Visual C++ 2013 Redistributable (x64)" $p = Get-Package | where {$_.Name -like "$vs*"} if($p -ne $null) { Write-Verbose "$vs is installed on server.." } else { Write-Error "Please install $vs on server before installing Hotfix." } } function Test-SqlDb { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $SqlServerInstance, [Parameter(Mandatory = $true)] [string] $SqlDbName ) $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $SqlServerInstance; Database = $SqlDbName; Integrated Security = True" do{ $open = $SqlConnection.OpenAsync() $SqlConnection.Close() $canceled = $open.IsCanceled $fault = $open.IsFaulted } while($canceled) if($fault) { return @{ Exists = $false } } else { return @{ Exists = $true } } } |