Improve install of VDD and VBCable

This commit is contained in:
James Stringer 2022-01-09 13:24:06 +01:00
parent a0d7fa1621
commit 11acb54e46
7 changed files with 243 additions and 25 deletions

View File

@ -7,6 +7,7 @@
SizeBytes = 40GB SizeBytes = 40GB
MemoryAmount = 8GB MemoryAmount = 8GB
CPUCores = 4 CPUCores = 4
NetworkSwitch = "Default Switch"
UnattendPath = "$PSScriptRoot"+"\autounattend.xml" UnattendPath = "$PSScriptRoot"+"\autounattend.xml"
GPUName = "AUTO" GPUName = "AUTO"
GPUResourceAllocationPercentage = 50 GPUResourceAllocationPercentage = 50
@ -103,6 +104,10 @@ param(
if((Test-Path -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Startup) -eq $true) {} Else {New-Item -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Startup -ItemType directory | Out-Null} if((Test-Path -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Startup) -eq $true) {} Else {New-Item -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Startup -ItemType directory | Out-Null}
if((Test-Path -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Shutdown) -eq $true) {} Else {New-Item -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Shutdown -ItemType directory | Out-Null} if((Test-Path -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Shutdown) -eq $true) {} Else {New-Item -Path $DriveLetter\Windows\system32\GroupPolicy\Machine\Scripts\Shutdown -ItemType directory | Out-Null}
if((Test-Path -Path $DriveLetter\ProgramData\Easy-GPU-P) -eq $true) {} Else {New-Item -Path $DriveLetter\ProgramData\Easy-GPU-P -ItemType directory | Out-Null} if((Test-Path -Path $DriveLetter\ProgramData\Easy-GPU-P) -eq $true) {} Else {New-Item -Path $DriveLetter\ProgramData\Easy-GPU-P -ItemType directory | Out-Null}
Copy-Item -Path $psscriptroot\VMScripts\VDDMonitor.ps1 -Destination $DriveLetter\ProgramData\Easy-GPU-P
Copy-Item -Path $psscriptroot\VMScripts\VBCableInstall.ps1 -Destination $DriveLetter\ProgramData\Easy-GPU-P
Copy-Item -Path $psscriptroot\VMScripts\ParsecVDDInstall.ps1 -Destination $DriveLetter\ProgramData\Easy-GPU-P
Copy-Item -Path $psscriptroot\VMScripts\ParsecPublic.cer -Destination $DriveLetter\ProgramData\Easy-GPU-P
Copy-Item -Path $psscriptroot\gpt.ini -Destination $DriveLetter\Windows\system32\GroupPolicy Copy-Item -Path $psscriptroot\gpt.ini -Destination $DriveLetter\Windows\system32\GroupPolicy
Copy-Item -Path $psscriptroot\User\psscripts.ini -Destination $DriveLetter\Windows\system32\GroupPolicy\User\Scripts Copy-Item -Path $psscriptroot\User\psscripts.ini -Destination $DriveLetter\Windows\system32\GroupPolicy\User\Scripts
Copy-Item -Path $psscriptroot\User\Install.ps1 -Destination $DriveLetter\Windows\system32\GroupPolicy\User\Scripts\Logon Copy-Item -Path $psscriptroot\User\Install.ps1 -Destination $DriveLetter\Windows\system32\GroupPolicy\User\Scripts\Logon
@ -4274,6 +4279,7 @@ param(
[string]$UnattendPath, [string]$UnattendPath,
[int64]$MemoryAmount, [int64]$MemoryAmount,
[int]$CPUCores, [int]$CPUCores,
[string]$NetworkSwitch,
[string]$GPUName, [string]$GPUName,
[float]$GPUResourceAllocationPercentage, [float]$GPUResourceAllocationPercentage,
[string]$SourcePath, [string]$SourcePath,
@ -4294,7 +4300,7 @@ param(
$MaxAvailableVersion = (Get-VMHostSupportedVersion).Version | Where-Object {$_.Major -lt 254}| Select-Object -Last 1 $MaxAvailableVersion = (Get-VMHostSupportedVersion).Version | Where-Object {$_.Major -lt 254}| Select-Object -Last 1
Convert-WindowsImage -SourcePath $SourcePath -Edition $Edition -VHDFormat $Vhdformat -VHDPath $VhdPath -DiskLayout $DiskLayout -UnattendPath $UnattendPath -GPUName $GPUName -Team_ID $Team_ID -Key $Key -SizeBytes $SizeBytes| Out-Null Convert-WindowsImage -SourcePath $SourcePath -Edition $Edition -VHDFormat $Vhdformat -VHDPath $VhdPath -DiskLayout $DiskLayout -UnattendPath $UnattendPath -GPUName $GPUName -Team_ID $Team_ID -Key $Key -SizeBytes $SizeBytes| Out-Null
if (Test-Path $vhdPath) { if (Test-Path $vhdPath) {
New-VM -Name $VMName -MemoryStartupBytes $MemoryAmount -VHDPath $VhdPath -Generation 2 -SwitchName "Default Switch" -Version $MaxAvailableVersion | Out-Null New-VM -Name $VMName -MemoryStartupBytes $MemoryAmount -VHDPath $VhdPath -Generation 2 -SwitchName $NetworkSwitch -Version $MaxAvailableVersion | Out-Null
Set-VM -Name $VMName -ProcessorCount $CPUCores -CheckpointType Disabled -LowMemoryMappedIoSpace 3GB -HighMemoryMappedIoSpace 32GB -GuestControlledCacheTypes $true -AutomaticStopAction ShutDown Set-VM -Name $VMName -ProcessorCount $CPUCores -CheckpointType Disabled -LowMemoryMappedIoSpace 3GB -HighMemoryMappedIoSpace 32GB -GuestControlledCacheTypes $true -AutomaticStopAction ShutDown
Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $false Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $false
$CPUManufacturer = Get-CimInstance -ClassName Win32_Processor | Foreach-Object Manufacturer $CPUManufacturer = Get-CimInstance -ClassName Win32_Processor | Foreach-Object Manufacturer
@ -4305,6 +4311,7 @@ param(
Set-VMProcessor -VMName $VMName -ExposeVirtualizationExtensions $true Set-VMProcessor -VMName $VMName -ExposeVirtualizationExtensions $true
} }
Set-VMHost -ComputerName $ENV:Computername -EnableEnhancedSessionMode $false Set-VMHost -ComputerName $ENV:Computername -EnableEnhancedSessionMode $false
Set-VMVideo -VMName $VMName -HorizontalResolution 1920 -VerticalResolution 1080
Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector
Enable-VMTPM -VMName $VMName Enable-VMTPM -VMName $VMName
Add-VMDvdDrive -VMName $VMName -Path $SourcePath Add-VMDvdDrive -VMName $VMName -Path $SourcePath

View File

@ -11,8 +11,6 @@ if (Test-Path HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninst
{} {}
else { else {
(New-Object System.Net.WebClient).DownloadFile("https://builds.parsecgaming.com/package/parsec-windows.exe", "C:\Users\$env:USERNAME\Downloads\parsec-windows.exe") (New-Object System.Net.WebClient).DownloadFile("https://builds.parsecgaming.com/package/parsec-windows.exe", "C:\Users\$env:USERNAME\Downloads\parsec-windows.exe")
(New-Object System.Net.WebClient).DownloadFile("https://builds.parsec.app/vdd/parsec-vdd-0.37.0.0.exe", "C:\Users\$env:USERNAME\Downloads\parsec-vdd.exe")
(New-Object System.Net.WebClient).DownloadFile("https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack43.zip", "C:\Users\$env:USERNAME\Downloads\VBCable.zip")
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | Out-File C:\ProgramData\Easy-GPU-P\admim.txt $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) | Out-File C:\ProgramData\Easy-GPU-P\admim.txt
Start-Process "C:\Users\$env:USERNAME\Downloads\parsec-windows.exe" -ArgumentList "/silent", "/shared","/team_id=$team_id","/team_computer_key=$key" -wait Start-Process "C:\Users\$env:USERNAME\Downloads\parsec-windows.exe" -ArgumentList "/silent", "/shared","/team_id=$team_id","/team_computer_key=$key" -wait
@ -22,23 +20,188 @@ if (Test-Path HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninst
$configfile | Out-File C:\ProgramData\Parsec\config.txt -Encoding ascii $configfile | Out-File C:\ProgramData\Parsec\config.txt -Encoding ascii
} }
if (!(Get-WmiObject Win32_VideoController | Where-Object name -like "VB-Audio Virtual Cable")) { Function ParsecVDDMonitorSetupScheduledTask {
New-Item -Path "C:\Users\$env:Username\Downloads\VBCable" -ItemType Directory| Out-Null $XML = @"
Expand-Archive -Path "C:\Users\$env:USERNAME\Downloads\VBCable.zip" -DestinationPath "C:\Users\$env:USERNAME\Downloads\VBCable" <?xml version="1.0" encoding="UTF-16"?>
$pathToCatFile = "C:\Users\$env:USERNAME\Downloads\VBCable\vbaudio_cable64_win7.cat" <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
$FullCertificateExportPath = "C:\Users\$env:USERNAME\Downloads\VBCable\VBCert.cer" <RegistrationInfo>
$VB = @{} <Description>Monitors the state of Parsec Virtual Display and repairs if broken</Description>
$VB.DriverFile = $pathToCatFile; <URI>\Monitor Parsec VDD State</URI>
$VB.CertName = $FullCertificateExportPath; </RegistrationInfo>
$VB.ExportType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert; <Triggers>
$VB.Cert = (Get-AuthenticodeSignature -filepath $VB.DriverFile).SignerCertificate; <LogonTrigger>
[System.IO.File]::WriteAllBytes($VB.CertName, $VB.Cert.Export($VB.ExportType)) <Enabled>true</Enabled>
Import-Certificate -CertStoreLocation Cert:\LocalMachine\TrustedPublisher -FilePath $VB.CertName | Out-Null <UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name)</UserId>
Start-Process -FilePath "C:\Users\$env:Username\Downloads\VBCable\VBCABLE_Setup_x64.exe" -ArgumentList '-i','-h' <Delay>PT2M</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value)</UserId>
<LogonType>S4U</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-file %programdata%\Easy-GPU-P\VDDMonitor.ps1</Arguments>
</Exec>
</Actions>
</Task>
"@
try {
Get-ScheduledTask -TaskName "Monitor Parsec VDD State" -ErrorAction Stop | Out-Null
Unregister-ScheduledTask -TaskName "Monitor Parsec VDD State" -Confirm:$false
}
catch {}
$action = New-ScheduledTaskAction -Execute 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe' -Argument '-file %programdata%\Easy-GPU-P\VDDMonitor.ps1'
$trigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -XML $XML -TaskName "Monitor Parsec VDD State" | Out-Null
}
Function VBCableInstallSetupScheduledTask {
$XML = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Description>Install VB Cable</Description>
<URI>\Install VB Cable</URI>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name)</UserId>
<Delay>PT2M</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value)</UserId>
<LogonType>S4U</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-file %programdata%\Easy-GPU-P\VBCableInstall.ps1</Arguments>
</Exec>
</Actions>
</Task>
"@
try {
Get-ScheduledTask -TaskName "Install VB Cable" -ErrorAction Stop | Out-Null
Unregister-ScheduledTask -TaskName "Install VB Cable" -Confirm:$false
}
catch {}
$action = New-ScheduledTaskAction -Execute 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe' -Argument '-file %programdata%\Easy-GPU-P\VBCableInstall.ps1'
$trigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -XML $XML -TaskName "Install VB Cable" | Out-Null
}
Function ParsecVDDInstallSetupScheduledTask {
$XML = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Description>Install Parsec Virtual Display Driver</Description>
<URI>\Install Parsec Virtual Display Driver</URI>
</RegistrationInfo>
<Triggers>
<LogonTrigger>
<Enabled>true</Enabled>
<UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name)</UserId>
<Delay>PT2M</Delay>
</LogonTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>$(([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value)</UserId>
<LogonType>S4U</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe</Command>
<Arguments>-file %programdata%\Easy-GPU-P\ParsecVDDInstall.ps1</Arguments>
</Exec>
</Actions>
</Task>
"@
try {
Get-ScheduledTask -TaskName "Install Parsec Virtual Display Driver" -ErrorAction Stop | Out-Null
Unregister-ScheduledTask -TaskName "Install Parsec Virtual Display Driver" -Confirm:$false
}
catch {}
$action = New-ScheduledTaskAction -Execute 'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe' -Argument '-file %programdata%\Easy-GPU-P\ParsecVDDInstall.ps1'
$trigger = New-ScheduledTaskTrigger -AtStartup
Register-ScheduledTask -XML $XML -TaskName "Install Parsec Virtual Display Driver" | Out-Null
} }
ParsecVDDMonitorSetupScheduledTask
VBCableInstallSetupScheduledTask
ParsecVDDInstallSetupScheduledTask
if (!(Get-WmiObject Win32_VideoController | Where-Object name -like "Parsec Virtual Display Adapter")) { Start-ScheduledTask -TaskName "Install VB Cable"
Get-PnpDevice | Where-Object {$_.friendlyname -like "Microsoft Hyper-V Video" -and $_.status -eq "OK"} | Disable-PnpDevice -confirm:$false Start-ScheduledTask -TaskName "Install Parsec Virtual Display Driver"
Start-Process "C:\Users\$env:USERNAME\Downloads\parsec-vdd.exe" -ArgumentList "/s" Start-ScheduledTask -TaskName "Monitor Parsec VDD State"
}

BIN
VMScripts/ParsecPublic.cer Normal file

Binary file not shown.

View File

@ -0,0 +1,10 @@
if (!(Get-WmiObject Win32_VideoController | Where-Object name -like "Parsec Virtual Display Adapter")) {
(New-Object System.Net.WebClient).DownloadFile("https://builds.parsec.app/vdd/parsec-vdd-0.37.0.0.exe", "C:\Users\$env:USERNAME\Downloads\parsec-vdd.exe")
while (((Get-ChildItem Cert:\LocalMachine\TrustedPublisher) | Where-Object {$_.Subject -like '*Parsec*'}) -eq $NULL) {
certutil -Enterprise -Addstore "TrustedPublisher" C:\ProgramData\Easy-GPU-P\ParsecPublic.cer
Start-Sleep -s 5
}
Get-PnpDevice | Where-Object {$_.friendlyname -like "Microsoft Hyper-V Video" -and $_.status -eq "OK"} | Disable-PnpDevice -confirm:$false
Start-Process "C:\Users\$env:USERNAME\Downloads\parsec-vdd.exe" -ArgumentList "/s"
}

View File

@ -0,0 +1,19 @@
if (!(Get-WmiObject Win32_SoundDevice | Where-Object name -like "VB-Audio Virtual Cable")) {
(New-Object System.Net.WebClient).DownloadFile("https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack43.zip", "C:\Users\$env:USERNAME\Downloads\VBCable.zip")
New-Item -Path "C:\Users\$env:Username\Downloads\VBCable" -ItemType Directory| Out-Null
Expand-Archive -Path "C:\Users\$env:USERNAME\Downloads\VBCable.zip" -DestinationPath "C:\Users\$env:USERNAME\Downloads\VBCable"
$pathToCatFile = "C:\Users\$env:USERNAME\Downloads\VBCable\vbaudio_cable64_win7.cat"
$FullCertificateExportPath = "C:\Users\$env:USERNAME\Downloads\VBCable\VBCert.cer"
$VB = @{}
$VB.DriverFile = $pathToCatFile;
$VB.CertName = $FullCertificateExportPath;
$VB.ExportType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert;
$VB.Cert = (Get-AuthenticodeSignature -filepath $VB.DriverFile).SignerCertificate;
[System.IO.File]::WriteAllBytes($VB.CertName, $VB.Cert.Export($VB.ExportType))
while (((Get-ChildItem Cert:\LocalMachine\TrustedPublisher) | Where-Object {$_.Subject -like '*Vincent Burel*'}) -eq $NULL) {
certutil -Enterprise -Addstore "TrustedPublisher" $VB.CertName
Start-Sleep -s 5
}
Start-Process -FilePath "C:\Users\$env:Username\Downloads\VBCable\VBCABLE_Setup_x64.exe" -ArgumentList '-i','-h'
}

19
VMScripts/VDDMonitor.ps1 Normal file
View File

@ -0,0 +1,19 @@
$Global:VDD
Function GetVDDState {
$Global:VDD = Get-PnpDevice | where {$_.friendlyname -like "Parsec Virtual Display Adapter"}
}
While (1 -gt 0) {
GetVDDSTate
If ($Global:VDD -eq $NULL){
Exit
}
Do {
Enable-PnpDevice -InstanceId $Global:VDD.InstanceId -Confirm:$false
Start-Sleep -s 5
GetVDDState
}
Until ($Global:VDD.Status -eq 'OK')
Start-Sleep -s 10
}

View File

@ -123,7 +123,7 @@
<CEIPEnabled>0</CEIPEnabled> <CEIPEnabled>0</CEIPEnabled>
</component> </component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComputerName>GPUP</ComputerName> <ComputerName>GPUP122</ComputerName>
<ProductKey>W269N-WFGWX-YVC9B-4J6C9-T83GX</ProductKey> <ProductKey>W269N-WFGWX-YVC9B-4J6C9-T83GX</ProductKey>
</component> </component>
</settings> </settings>