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"; $proxyStubClsid = '00020420-0000-0000-C000-000000000046' $proxyStubClsid32 = $proxyStubClsid $typeLibVersion = '1.0' if ($env:PROCESSOR_ARCHITECTURE -eq 'AMD64') { $architectureSeparator = '\Wow6432Node' } else { $architectureSeparator = '\' } $template = New-Object System.Collections.Generic.List[System.Object]; # CLSID keys $template.AddRange( @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}" Values = @( @{ Name = '(default)' Value = $classLabel }, @{ Name = 'AppID' Value = "{$appId}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}\LocalServer32" Values = @( @{ Name = '(default)' Value = $comServerPath } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}\ProgID" Values = @( @{ Name = '(default)' Value = $progId } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}\Programmable" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}\TypeLib" Values = @( @{ Name = '(default)' Value = $typeLibId } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\CLSID\{$clsid}\VersionIndependentProgID" Values = @() } ) ); # Interface keys $template.AddRange( @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$interfaceId}" Values = @( @{ Name = '(default)' Value = $interfaceName } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$interfaceId}\ProxyStubClsid" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$interfaceId}\ProxyStubClsid32" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$interfaceId}\TypeLib" Values = @( @{ Name = '(default)' Value = "{$typeLibId}" }, @{ Name = 'Version' Value = $typeLibVersion } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$eventInterfaceId}" Values = @( @{ Name = '(default)' Value = $eventInterfaceName } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$eventInterfaceId}\ProxyStubClsid" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$eventInterfaceId}\ProxyStubClsid32" Values = @( @{ Name = '(default)' Value = "{$proxyStubClsid32}" } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\Interface\{$eventInterfaceId}\TypeLib" Values = @( @{ Name = '(default)' Value = "{$typeLibId}" } @{ Name = 'Version' Value = $typeLibVersion } ) } ) ) # Prog ID keys $template.AddRange( @( @{ 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}" } ) } ) ) # TypeLib keys (add to both standard and Wow6432Node if architecture is x64) if ($architectureSeparator -eq '\') { $typeLibIterations = 1 } else { $typeLibIterations = 2 } for ($i = 0; $i -lt $typeLibIterations; $i++) { if ($i -eq 1) { $architectureSeparator = '\' } $template.AddRange( @( @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}\$typeLibVersion" Values = @( @{ Name = '(default)' Value = $typeLibLabel } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}\$typeLibVersion\0" Values = @() }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}\$typeLibVersion\0\win32" Values = @( @{ Name = '(default)' Value = $comServerNetworkPath } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}\$typeLibVersion\FLAGS" Values = @( @{ Name = '(default)' Value = '0' } ) }, @{ Key = "$($registryHive):\SOFTWARE\Classes$($architectureSeparator)\TypeLib\{$typeLibId}\$typeLibVersion\HELPDIR" Values = @( @{ Name = '(default)' Value = "$comServerDir\" } ) } ) ) } function DoAction { param( [Parameter(Mandatory=$true)] [array] $template ) foreach ($keyEl in $template) { if ($action -eq 'import') { #Write-Debug $keyEl.Key try { $key = New-Item -Path $keyEl.Key -Force Write-Host "Created registry key: $($key.PSPath)" } catch { Write-Error "Failed to create registry key: $($keyEl.Key)" continue } foreach ($valueEl in $keyEl.Values) { try { New-ItemProperty -Path $keyEl.Key -Name $valueEl.Name -Value $valueEl.Value -PropertyType 'String' -Force Write-Host "Created registry value: $($valueEl.Name) in $($keyEl.Key)" } catch { Write-Error "Failed to create registry value: $($valueEl.Name) in $($keyEl.Key)" continue } } } } } DoAction $template