param ( [Parameter(Mandatory=$true)] [string] $airline = 'ua', [Parameter(Mandatory=$true)] [ValidateSet('query', 'delete', 'import')] [string] $action, [Parameter(Mandatory=$true)] [ValidateSet('gate', 'checkin')] [string] $comServerType, [Parameter(Mandatory=$false)] [ValidateSet('HKEY_LOCAL_MACHINE', 'HKEY_CURRENT_USER', 'HKLM', 'HKCU')] [string] $registryHive = 'HKEY_LOCAL_MACHINE', [Parameter(Mandatory=$false)] [string] $comServerDir, [Parameter(Mandatory=$false)] [string] $comServerFileName, [Parameter(Mandatory=$false)] [switch] $enableDebugging = $false ) if ($enableDebugging) { $DebugPreference = 'Continue' } else { $DebugPreference = 'SilentlyContinue' } switch ($airline) { 'as' { Write-Error "Not yet implemented for airline ""$airline""" exit 1 } '4n' { Write-Error "Not yet implemented for airline ""$airline""" exit 1 } 'nz' { Write-Error "Not yet implemented for airline ""$airline""" exit 1 } 'ua' { switch ($comServerType) { 'checkin' { $clsid = '35578409-F9F5-43e8-A6BD-8B77199ED854' $appId = '91D04D72-DCB6-11D3-957D-00409500D5AD' $classLabel = "QWDev Class" $interfaceId = '6B15E61A-381F-41e7-8B65-BA386473FE8C' $interfaceName = 'IQWDev' $eventInterfaceId = '17DCFB07-18A9-4ffe-B34D-37B91D809C41' $eventInterfaceName = '_IQWDevEvents' $typeLibId='CD886C7B-B61C-49cf-B3B8-90DB303A502A' $typeLibLabel = 'QSRDevice 1.0 Type Library' $versionIndependentProgId = 'QSRDevice.QSRDev'; } 'gate' { $clsid = '3F52625C-F66C-43F5-B538-CDF7331E0B7D' $appId = 'C123476B-ABB6-4bcc-B557-2FDC0CDCD6A8' $classLabel = "QSRDev Class" $interfaceId = 'D178FEAC-4969-45b4-92BF-4582EA5C6F47' $interfaceName = 'IQSRDev' $eventInterfaceId = 'FDE206D5-EB3E-4DB1-AC3E-6CF314417443' $eventInterfaceName = '_IQSRDevEvents' $typeLibId='FB2C3447-9D8D-4AD0-9234-A163505FC3AE' $typeLibLabel = 'QWDevice 1.0 Type Library' $versionIndependentProgId = 'QWDevice.QWDev'; } } } default { Write-Error "Unknown airline: $airline" exit 1 } } switch ($action) { 'delete' { } 'import' { if (!$comServerDir) { Write-Error "Missing COM server directory" exit 1 } if (!$comServerFileName) { Write-Error "Missing COM server file name" exit 1 } } 'query' { } default { Write-Error "Unknown action: $action" exit 1 } } switch ($registryHive) { 'HKCU' { } 'HKLM' { } 'HKEY_CURRENT_USER' { $registryHive = 'HKCU' } 'HKEY_LOCAL_MACHINE' { $registryHive = 'HKLM' } default { Write-Error "Invalid registry hive: $registryHive" exit 1 } } $comServerDir = $comServerDir.TrimEnd('\') $comServerPath = "$comServerDir\$comServerFileName" if (![System.IO.Path]::IsPathRooted($comServerPath)) { Write-Error "Provided COM server path is not absolute: $comServerPath" exit 1 } $comServerNetworkPath = $comServerPath if (!(Test-Path $comServerPath)) { Write-Warning "COM server path does not exist: $comServerPath" } # COM servers use the network path in some registry keys when self-registering, so attempt to discover it. try { $driveLetter = $comServerPath.Substring(0, 1) $networkPathToDrive = (Get-PSDrive | Where-Object {$_.Name -eq $driveLetter}).DisplayRoot if ($networkPathToDrive) { $rootPathWithoutDrive = $comServerPath.Substring(2) $comServerNetworkPath = "$networkPathToDrive$rootPathWithoutDrive" } } catch { Write-Error "An error occurred trying to discover network path to COM server at $comServerPath" } $progId = "$versionIndependentProgId.1"; $proxyStubClsid32 = '00020420-0000-0000-C000-000000000046' $typeLibVersion = '1.0' function Get-ClsidKeys { param( [Parameter(Mandatory=$true)] [string] $architectureNode ) return @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}" Values = @( @{ Name = '(default)' Value = $classLabel }, @{ Name = 'AppID' Value = "{$appId}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}\LocalServer32" Values = @( @{ Name = '(default)' Value = $comServerPath } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}\ProgID" Values = @( @{ Name = '(default)' Value = $progId } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}\Programmable" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}\TypeLib" Values = @( @{ Name = '(default)' Value = $typeLibId } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)CLSID\{$clsid}\VersionIndependentProgID" Values = @() } ) } function Get-InterfaceKeys { param( [Parameter(Mandatory=$true)] [string] $architectureNode ) return @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$interfaceId}" Values = @( @{ Name = '(default)' Value = $interfaceName } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$interfaceId}\ProxyStubClsid32" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid32}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$interfaceId}\TypeLib" Values = @( @{ Name = '(default)' Value = "{$typeLibId}" }, @{ Name = 'Version' Value = $typeLibVersion } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$eventInterfaceId}" Values = @( @{ Name = '(default)' Value = $eventInterfaceName } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$eventInterfaceId}\ProxyStubClsid32" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid32}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)Interface\{$eventInterfaceId}\TypeLib" Values = @( @{ Name = '(default)' Value = "{$typeLibId}" } @{ Name = 'Version' Value = $typeLibVersion } ) } ) } function Get-ProgIdKeys { return @( @{ Key = "$($registryHive):\SOFTWARE\Classes\$progId" Values = @( @{ Name = '(default)' Value = $classLabel } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes\$progId\CLSID" Values = @( @{ Name = '(default)' Value = "{$clsid}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes\$progId\CurVer" Values = @( @{ Name = '(default)' Value = $versionIndependentProgId } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes\$versionIndependentProgId" Values = @( @{ Name = '(default)' Value = $classLabel } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes\$versionIndependentProgId\CLSID" Values = @( @{ Name = '(default)' Value = "{$clsid}" } ) } ) } function Get-TypeLibKeys { param( [Parameter(Mandatory=$true)] [string] $architectureNode ) return @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}\$typeLibVersion" Values = @( @{ Name = '(default)' Value = $typeLibLabel } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}\$typeLibVersion\0" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}\$typeLibVersion\0\win32" Values = @( @{ Name = '(default)' Value = $comServerNetworkPath } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}\$typeLibVersion\FLAGS" Values = @( @{ Name = '(default)' Value = '0' } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureNode)TypeLib\{$typeLibId}\$typeLibVersion\HELPDIR" Values = @( @{ Name = '(default)' Value = "$comServerDir\" } ) } ) } function Get-Keys { param( [Parameter(Mandatory=$false)] [switch] $bothArchitectures = $false ) if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64') { $wow6432Node = '\Wow6432Node\' } else { $wow6432Node = '\' } $keys = New-Object System.Collections.Generic.List[System.Object] $keys.AddRange((Get-ProgIdKeys)) $keys.AddRange((Get-ClsidKeys -architectureNode $wow6432Node)) $keys.AddRange((Get-InterfaceKeys -architectureNode $wow6432Node)) $keys.AddRange((Get-TypeLibKeys -architectureNode $wow6432Node)) if ($wow6432Node -ne '\') { if ($bothArchitectures) { $keys.AddRange((Get-ClsidKeys -architectureNode $wow6432Node)) } $keys.AddRange((Get-InterfaceKeys -architectureNode '\')) $keys.AddRange((Get-TypeLibKeys -architectureNode '\')) } return $keys } switch ($action) { 'delete' { $keys = Get-Keys -bothArchitectures foreach ($key in $keys) { try { Write-Debug "Deleting key: $($key.Key)" # Remove-Item -Path $key.Key -Recurse -Force # Write-Host "Deleted registry key: $($key.Key)" } catch { Write-Error "Failed to delete key: $($key.Key)" continue } } } 'import' { $keys = Get-Keys foreach ($key in $keys) { try { Write-Debug "Importing key: $($key.Key)" # $newKey = New-Item -Path $keyEl.Key -Force # Write-Host "Created registry key: $($newKey.PSPath)" } catch { Write-Error "Failed to create key: $($key.Key)" continue } foreach ($value in $key.Values) { try { Write-Debug "Importing value: $($value.Name):$($value.Value)" #New-ItemProperty -Path $key.Key -Name $value.Name -Value $value.Value -PropertyType 'String' -Force #Write-Host "Created registry value: $($value.Name) in $($key.Key)" } catch { Write-Error "Failed to create entry: $($value.Name) in $($key.Key)" continue } } } } default { $keys = Get-Keys -bothArchitectures foreach ($key in $keys) { Write-Debug "[$($key.Key)]" foreach ($valuePair in $key.Values) { try { $value = Get-ItemPropertyValue -Path $key.Key -Name $valuePair.Name -ErrorAction Stop } catch { Write-Debug "Failed to find value for $($valuePair.Name)" continue } Write-Host "$($valuePair.Name)=$($value)" } } } }