DSCResources/VE_ROACommon/VE_ROACommon.psm1
# Localized messages data LocalizedData { # culture="en-US" ConvertFrom-StringData @' StartingProcess = Starting process '{0}' with parameters '{1}'. StartingProcessAs = Starting process as user '{0}'. ProcessLaunched = Process id '{0}' successfully started. WaitingForProcessToExit = Waiting for process id '{0}' to exit. ProcessExited = Process id '{0}' exited with code '{1}'. OpeningMSIDatabase = Opening MSI database '{0}'. '@ } function ResolveProductName { <# .SYNOPSIS Resolves the RES ONE Automation agent to the correct product name. #> [CmdletBinding()] param ( ## RES ONE Automation component version to be installed, i.e. 8.0.3.0 [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $Version, [Parameter(Mandatory)] [ValidateSet('Console','Dispatcher','Agent')] [System.String] $Component ) [System.Version] $Version = $Version; switch ($Version.Major) { 7 { if ($Version.Minor -eq 0) { $msiProductName = 'RES Automation Manager 2014'; } elseif ($Version.Minor -eq 5) { $msiProductName = 'RES ONE Automation 2015'; } } Default { throw "Version '$($Version.Tostring())' is not currently supported :(."; } } #end switch version switch ($Component) { 'Console' { ## Determine whether we're on the RTM release if ($Version.Build -eq 0) { $msiProductName = '{0}' -f $msiProductName; } else { $msiProductName = '{0} SR{1}' -f $msiProductName, $Version.Build; } } 'Dispatcher' { if ($Version.Build -eq 0) { $msiProductName = '{0} Dispatcher+' -f $msiProductName; } else { $msiProductName = '{0} SR{1} Dispatcher+' -f $msiProductName, $Version.Build; } } Default { #Agent if ($Version.Build -eq 0) { $msiProductName = '{0} {1}' -f $msiProductName, $Component; } else { $msiProductName = '{0} SR{1} {2}' -f $msiProductName, $Version.Build, $Component; } } #end Default } #end switch component return $msiProductName; } #end function ResolveProductName function ResolveSetupPath { <# .SYNOPSIS Resolves the RES ONE Automation agent to the correct .msi #> [CmdletBinding()] param ( ## File path containing the RES ONE Automation MSIs or the literal path to the Agent MSI. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $Path, ## RES ONE Automation component version to be installed, i.e. 8.0.3.0 [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Version, ## The specified Path is a literal file reference (bypasses the $Versioncheck). [Parameter()] [ValidateNotNull()] [System.Management.Automation.SwitchParameter] $IsLiteralPath, [Parameter(Mandatory)] [ValidateSet('Agent')] [System.String] $Component, ## Catch-all to permit splatting [Parameter(ValueFromRemainingArguments)] $Arguments ) if (-not $IsLiteralPath) { [System.Version] $Version = $Version; switch ($Component) { 'Agent' { switch ($Version.Major) { 7 { if ($Version.Minor -eq 0) { $setup = 'RES-AM-Agent-{0}.msi' -f $Version.ToString(); } elseif ($Version.Minor -eq 5) { $setup = 'RES-ONE-Automation-Agent-{0}.msi' -f $Version.ToString(); } } Default { throw "Version '$($Version.Tostring())' is not currently supported :(."; } } $Path = Join-Path -Path $Path -ChildPath $setup; } } #end switch component } #end if not literal path return $Path; } #end function ResolveSetupPath function GetWindowsInstallerPackageProperty { <# .SYNOPSIS This cmdlet retrieves product name from a Windows Installer MSI database. .DESCRIPTION This function uses the WindowInstaller COM object to pull all values from the Property table from a MSI package. .NOTES Adapted from http://www.scconfigmgr.com/2014/08/22/how-to-get-msi-file-information-with-powershell/ #> [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName='Path')] [ValidateNotNullOrEmpty()] [Alias('PSPath','FullName')] [System.String] $Path, [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName, ParameterSetName = 'LiteralPath')] [ValidateNotNullOrEmpty()] [System.String] $LiteralPath, [Parameter(Position = 1, ValueFromPipelineByPropertyName)] [ValidateSet('ProductCode', 'ProductVersion', 'ProductName', 'UpgradeCode')] [System.String] $Property = 'ProductCode' ) begin { if ($PSCmdlet.ParameterSetName -eq 'Path') { $LiteralPath += $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path); } # end if } #end begin process { $windowsInstaller = New-Object -ComObject WindowsInstaller.Installer; Write-Verbose -Message ($localizedData.OpeningMSIDatabase -f $LiteralPath); try { $msiDatabase = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @("$LiteralPath", 0)); $query = "SELECT Value FROM Property WHERE Property = '$Property'"; $view = $msiDatabase.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $msiDatabase, $query); $view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null); $record = $view.GetType().InvokeMember('Fetch','InvokeMethod', $null, $view, $null); $value = $record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1); return $value; } catch { throw; } } #end process } #end function Get-WindowsInstallerPackageProperty function StartWaitProcess { <# .SYNOPSIS Starts and waits for a process to exit. .NOTES This is an internal function and shouldn't be called from outside. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([System.Int32])] param ( # Path to process to start. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $FilePath, # Arguments (if any) to apply to the process. [Parameter()] [AllowNull()] [System.String[]] $ArgumentList, # Credential to start the process as. [Parameter()] [AllowNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential, # Working directory [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $WorkingDirectory = (Split-Path -Path $FilePath -Parent) ) process { $startProcessParams = @{ FilePath = $FilePath; WorkingDirectory = $WorkingDirectory; NoNewWindow = $true; PassThru = $true; }; $displayParams = '<None>'; if ($ArgumentList) { $displayParams = [System.String]::Join(' ', $ArgumentList); $startProcessParams['ArgumentList'] = $ArgumentList; } Write-Verbose ($localizedData.StartingProcess -f $FilePath, $displayParams); if ($Credential) { Write-Verbose ($localizedData.StartingProcessAs -f $Credential.UserName); $startProcessParams['Credential'] = $Credential; } if ($PSCmdlet.ShouldProcess($FilePath, 'Start Process')) { $process = Start-Process @startProcessParams -ErrorAction Stop; } if ($PSCmdlet.ShouldProcess($FilePath, 'Wait Process')) { Write-Verbose ($localizedData.ProcessLaunched -f $process.Id); Write-Verbose ($localizedData.WaitingForProcessToExit -f $process.Id); $process.WaitForExit(); $exitCode = [System.Convert]::ToInt32($process.ExitCode); Write-Verbose ($localizedData.ProcessExited -f $process.Id, $exitCode); } return $exitCode; } #end process } #end function StartWaitProcess function GetRAMSiteLicense { <# .SYNOPSIS Retrieves a RES ONE Automation Site License directory from the database. .NOTES This cmdlet currently only support Microsoft SQL servers. #> [CmdletBinding(DefaultParameterSetName='SQLAuth')] param ( # Database server to connect to [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.String] $Server, # Database to connect to [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $Database, # SQL authentication username [Parameter(Mandatory)] [ValidateNotNull()] [System.Management.Automation.PSCredential] $Credential ) process { $sqlConnectionString = 'Data Source={0};Initial Catalog={1};User Id={2};Password={3};' -f $Server, $Database, $Credential.UserName, $Credential.GetNetworkCredential().Password; $sqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -Property @{ 'ConnectionString' = $sqlConnectionString; }; $sqlConnection.Open(); $sqlCommand = $sqlConnection.CreateCommand(); $sqlCommand.CommandText = 'SELECT strValue AS License FROM tblSettings WHERE lngSetting = 6'; $sqlDataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $sqlCommand; $dataSet = New-Object System.Data.DataSet; [ref] $null = $sqlDataAdapter.Fill($dataSet); $sqlConnection.Close(); $dirtySiteLicense = "RES-$(($dataSet.Tables[0].License).Replace('{','').Replace('}',''))"; $cleanSiteLicense = $dirtySiteLicense.Insert(8, '-').Insert(33, '-').Insert(38, '-'); return $cleanSiteLicense; } } #end function GetRAMSiteLicense function GetProductEntry { <# .NOTES https://github.com/PowerShell/xPSDesiredStateConfiguration/blob/dev/DSCResources/MSFT_xPackageResource/MSFT_xPackageResource.psm1 #> param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $IdentifyingNumber, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $InstalledCheckRegHive = 'LocalMachine', [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $InstalledCheckRegKey, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $InstalledCheckRegValueName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $InstalledCheckRegValueData ) $uninstallKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'; $uninstallKeyWow64 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'; if ($IdentifyingNumber) { $keyLocation = "$uninstallKey\$identifyingNumber"; $item = Get-Item $keyLocation -ErrorAction SilentlyContinue; if (-not $item) { $keyLocation = "$uninstallKeyWow64\$identifyingNumber"; $item = Get-Item $keyLocation -ErrorAction SilentlyContinue; } return $item; } foreach ($item in (Get-ChildItem -ErrorAction Ignore $uninstallKey, $uninstallKeyWow64)) { if ($Name -eq (GetLocalizableRegKeyValue $item 'DisplayName')) { return $item; } } if ($InstalledCheckRegKey -and $InstalledCheckRegValueName -and $InstalledCheckRegValueData) { $installValue = $null; #if 64bit OS, check 64bit registry view first if ((Get-WmiObject -Class Win32_OperatingSystem -ComputerName 'localhost' -ErrorAction SilentlyContinue).OSArchitecture -eq '64-bit') { $installValue = GetRegistryValueIgnoreError $InstalledCheckRegHive "$InstalledCheckRegKey" "$InstalledCheckRegValueName" Registry64; } if ($installValue -eq $null) { $installValue = GetRegistryValueIgnoreError $InstalledCheckRegHive "$InstalledCheckRegKey" "$InstalledCheckRegValueName" Registry32; } if ($installValue) { if ($InstalledCheckRegValueData -and $installValue -eq $InstalledCheckRegValueData) { return @{ Installed = $true; } } } } return $null; } #end function GetProductEntry function GetRegistryValueIgnoreError { <# .NOTES https://github.com/PowerShell/xPSDesiredStateConfiguration/blob/dev/DSCResources/MSFT_xPackageResource/MSFT_xPackageResource.psm1 #> param ( [arameter(Mandatory)] [Microsoft.Win32.RegistryHive] $RegistryHive, [Parameter(Mandatory)] [System.String] $Key, [Parameter(Mandatory)] [System.String] $Value, [Parameter(Mandatory)] [Microsoft.Win32.RegistryView] $RegistryView ) try { $baseKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey($RegistryHive, $RegistryView); $subKey = $baseKey.OpenSubKey($Key); if($subKey -ne $null) { return $subKey.GetValue($Value); } } catch { $exceptionText = ($_ | Out-String).Trim(); Write-Verbose "Exception occured in Get-RegistryValueIgnoreError: $exceptionText"; } return $null; } #end function GetRegistryValueIgnoreError function GetLocalizableRegKeyValue { <# .NOTES https://github.com/PowerShell/xPSDesiredStateConfiguration/blob/dev/DSCResources/MSFT_xPackageResource/MSFT_xPackageResource.psm1 #> param ( [Parameter()] [System.Object] $RegKey, [Parameter()] [System.String] $ValueName ) $res = $RegKey.GetValue("{0}_Localized" -f $ValueName); if (-not $res) { $res = $RegKey.GetValue($ValueName); } return $res; } #end function GetLocalizableRegKeyValue |