Skip to content

Instantly share code, notes, and snippets.

@ThioJoe
Last active January 11, 2025 01:19
Show Gist options
  • Save ThioJoe/96d911749c18f9d64e2c60cdc11fa62f to your computer and use it in GitHub Desktop.
Save ThioJoe/96d911749c18f9d64e2c60cdc11fa62f to your computer and use it in GitHub Desktop.
PowerShell script to copy GPU drivers to Hyper-V Virtual Machine for passthrough.
# Description: This script will automatically copy the necessary GPU drivers from your current host machine into a Hyper-V Virtual Machine
# so you can pass through the GPU to the VM. You should run this whenever you update your graphics drivers on the host.
#
# Author: ThioJoe -- https://github.com/ThioJoe
#
# Note: Currently this only works for Nvidia GPUs. But it does support if you have multiple GPUs.
#
# OPTIONAL ARGUMENTS:
# -debug | Enables debug messages that pause the script for each step (No additional string required, just add -debug)
# -name | Sets the virtual machine name so it doesn't need to ask
# -username | The username for the admin account on the VM to use. Otherwise it will prompt when running script
# -password | The password for the admin account on the VM to use. Otherwise it will prompt when running script
#
# Example: .\Whatever-Script-Name.ps1 -debug -name Whatever_VM_Name -username blah -password somepassword
# Initialize variables
$enable_debug = $false
$VMNameArgument = $null
$Username = $null
$Password = $null
# Process command line arguments
for ($i = 0; $i -lt $args.Length; $i++) {
$currArg = $args[$i].ToLower()
switch ($currArg) {
"-debug" {
$enable_debug = $true
}
"-name" {
if ($args.Length -gt $i + 1) {
$VMNameArgument = $args[$i + 1]
$i++
}
}
"-username" {
if ($args.Length -gt $i + 1) {
$Username = $args[$i + 1]
$i++
}
}
"-password" {
if ($args.Length -gt $i + 1) {
$Password = $args[$i + 1] | ConvertTo-SecureString -AsPlainText -Force
$i++
}
}
}
}
# Get VM Name - First checks if there is an argument giving the name
# If no argument is given, it prompts the user
# It tests if the VM name is valid. If it is not, or the argument is invalid, it will prompt user again
function Get-VMName {
param (
[string]$NameFromArgument
)
if ($NameFromArgument) {
$vm = Get-VM -Name $NameFromArgument -ErrorAction SilentlyContinue
if ($vm) {
return $NameFromArgument
} else {
Write-Host "VM with name '$NameFromArgument' not found. Are you sure you're running this script as administrator?" -ForegroundColor Red
}
}
do {
$VMName = Read-Host "Please enter the name of the VM"
$vm = Get-VM -Name $VMName -ErrorAction SilentlyContinue
if (-not $vm) {
Write-Host "VM with name '$VMName' not found. Are you sure you're running this script as administrator?" -ForegroundColor Red
}
} while (-not $vm)
return $VMName
}
# Function to handle debug messages
function Show-DebugMessage {
param (
[string]$Message
)
if ($enable_debug) { Read-Host "Debug Step: $Message - Press Enter to continue..." }
}
function Handle-CredentialError {
Write-Host "The credential is invalid. Please ensure you're entering the correct credentials." -ForegroundColor Red
Write-Host " > In the 'username' box be sure to enter the username just as it appears from within the virtual machine." -ForegroundColor Red
Read-Host "Press Enter to exit..." # This line will pause the script
return
}
function Handle-AdminError {
Write-Host "Error: The input VMName parameter does not resolve to any virtual machine." -ForegroundColor Red
Write-Host " > Likely reason is this script must be run as administrator." -ForegroundColor Red
Read-Host "Press Enter to exit..." # This line will pause the script
}
# -----------------------------------------------------------------------------------------------------------------------
# ----------------------------------------------------- BEGIN -----------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------------
# Get VM Name from arguments or user
$VMName = Get-VMName -NameFromArgument $VMNameArgument
# Create a new persistent PowerShell session to the VM
Write-Host ""
Write-Host "Next you will need to enter the account credentials of an admin account on the VM in the pop up box."
Write-Host ""
try {
if ($Username -and $Password) {
$Credential = New-Object System.Management.Automation.PSCredential ($Username, $Password)
} else {
Write-Host "Enter the account credentials of an admin account on the VM."
Read-Host "Press Enter to continue..." # This line will pause the script
$Credential = Get-Credential
}
$s = New-PSSession -VMName $VMName -Credential $Credential -ErrorAction Stop
} catch {
if ($_.Exception.Message -match "The credential is invalid" -or $_.FullyQualifiedErrorId -match "PSSessionStateBroken") {
Handle-CredentialError
} elseif ($_.Exception.Message -match "The input VMName" -or $_.FullyQualifiedErrorId -match "InvalidVMNameNotSingle") {
Handle-AdminError
} else {
Write-Error "An unexpected error occurred: $_"
Read-Host "Press Enter to exit..." # This line will pause the script
}
return
}
Write-Host "`nPowerShell Session Established. Beginning... `n"
# Clear existing nv_ (Desktop) and nvmii (Mobile) folders in HostDriverStore\FileRepository on the guest (Virtual Machine)
Show-DebugMessage "Clearing Existing nv_ and nvmii folders in FileRepository on Guest VM"
Write-Host "`n Removing old nv_ and nvmii folders in FileRepository on VM... `n"
$remotePath = "C:\Windows\System32\HostDriverStore\FileRepository"
Invoke-Command -Session $s -ScriptBlock {
param ($Path)
Get-ChildItem -Path $Path -Directory | Where-Object { $_.Name -like "nv_*" -or $_.Name -like "nvmii*" } | ForEach-Object {
Remove-Item -Path $_.FullName -Recurse -Force
}
} -ArgumentList $remotePath
# Copy nv* files from System32 (excluding nvspinfo.exe and NvAgent.dll)
Show-DebugMessage "Copying nv* files to Guest VM"
Write-Host "`n Copying nv* files to Guest VM system32 directory... `n"
$system32Path = "C:\Windows\System32"
$vmSystem32Path = "C:\Windows\System32"
$excludeFiles = @("nvspinfo.exe", "NvAgent.dll")
Get-ChildItem -Path $system32Path -Filter "nv*" | Where-Object { $excludeFiles -notcontains $_.Name -and -not $_.PSIsContainer } | ForEach-Object {
$sourcePath = $_.FullName
$destinationPath = Join-Path -Path $vmSystem32Path -ChildPath $_.Name
Copy-Item -ToSession $s -Path $sourcePath -Destination $destinationPath -Recurse
}
# Sets temporary directory on local host
$tempDirectory = "$env:TEMP\NVDriverZips"
# Cleanup Any Previous Leftover Host Temp Directories, if they exist
if (Test-Path $tempDirectory) {
Show-DebugMessage "Removing Previous temporary directory $tempDirectory"
Remove-Item -Path $tempDirectory -Recurse -Force
}
# Create temporary directory for storing zip files
Show-DebugMessage "Creating temporary directory $tempDirectory"
New-Item -Path $tempDirectory -ItemType Directory -Force
# Copy nv_ folders from DriverStore\FileRepository
Show-DebugMessage "Zipping and copying nv_ and nvmii folders to HostDriverStore\FileRepository"
Write-Host "`n Zipping nv_ and nvmii folders and copying to HostDriverStore\FileRepository on VM `n"
$driverStorePath = "C:\Windows\System32\DriverStore\FileRepository"
$vmHostDriverStorePath = "C:\Windows\System32\HostDriverStore\FileRepository"
$vmTempPath = "C:\GPU_DRIVER_COPY_TEMP"
# Cleanup & Create Temp Directory: Check for and delete any previous existing temporary directory on VM, then create new one
Show-DebugMessage "Removing existing temporary directory on VM if applicable, and creating new temp directory: $vmTempPath"
Invoke-Command -Session $s -ScriptBlock {
param ($Path, $EnableDebug)
if (Test-Path $Path) {
if ($EnableDebug) { Write-Host "Old temporary path found and is being removed: $Path" }
Remove-Item -Path $Path -Recurse -Force
}
if ($EnableDebug) { Write-Host "New temporary directory is being created: $Path" }
New-Item -Path $Path -ItemType Directory -Force
} -ArgumentList $vmTempPath, $enable_debug
# Get folders in FileRepository beginning with nv_ or nvmii to copy over.
Get-ChildItem -Path $driverStorePath -Directory | Where-Object { $_.Name -like "nv_*" -or $_.Name -like "nvmii*" } | ForEach-Object {
$folderName = $_.Name
$zipPath = Join-Path -Path $tempDirectory -ChildPath "$folderName.zip"
Show-DebugMessage "Compressing folder $folderName to zip file to copy to VM."
# Use a conditional to zip either via pipeline approach on Windows PowerShell 5
# or the traditional Compress-Archive approach on PS 7+.
if ($PSVersionTable.PSVersion.Major -lt 7) {
# Create a subfolder in the temp directory to hold the copied contents
$tempFolder = Join-Path $tempDirectory $folderName
# If (by some chance) it already exists, remove it
if (Test-Path $tempFolder) {
Remove-Item -Path $tempFolder -Recurse -Force
}
# Copy-Item in a pipeline, then compress
Copy-Item -Path $_.FullName -Destination $tempFolder -Recurse -Force -PassThru |
Get-ChildItem |
Compress-Archive -DestinationPath $zipPath -CompressionLevel NoCompression
}
else {
Compress-Archive -Path "$($_.FullName)\*" -DestinationPath $zipPath -CompressionLevel NoCompression
}
# Now copy the zip over to the VM
$vmZipPath = Join-Path -Path $vmTempPath -ChildPath "$folderName.zip"
Show-DebugMessage "Copying zip file to VM temp directory"
try {
Copy-VMFile -Name $VMName -FileSource Host -SourcePath $zipPath -DestinationPath $vmZipPath -Force -CreateFullPath
} catch {
Write-Warning "Error copying zip file. Will try using another method."
Copy-Item -ToSession $s -Path $zipPath -Destination $vmZipPath
}
}
# Extract zip files on VM
Show-DebugMessage "Extracting Zip File to destination within VM"
Invoke-Command -Session $s -ScriptBlock {
param ($ZipDirectory, $Destination, $EnableDebug)
Get-ChildItem -Path $ZipDirectory -Filter "*.zip" | ForEach-Object {
$zipFile = $_.FullName
$extractPath = Join-Path -Path $Destination -ChildPath $_.BaseName
if ($EnableDebug) { Write-Host "Expanding zip file: $zipFile to $extractPath" }
Expand-Archive -Path $zipFile -DestinationPath $extractPath
Remove-Item -Path $zipFile
}
} -ArgumentList $vmTempPath, $vmHostDriverStorePath, $enable_debug
# Clean up local temporary directory
Show-DebugMessage "Removing local temporary directory."
Remove-Item -Path $tempDirectory -Recurse -Force
# Remove temporary directory on VM
Show-DebugMessage "Removing VM Temporary Directory"
Invoke-Command -Session $s -ScriptBlock {
param ($Path)
Remove-Item -Path $Path -Recurse -Force
} -ArgumentList $vmTempPath
# Close the session
Show-DebugMessage "Ending Powershell Session"
Remove-PSSession $s
Write-Host "`n--------------------------------------------------------------------------"
Write-Host "Finished. You should now restart the virtual machine." -ForegroundColor Green
Write-Host "`nIf you haven't allocated the GPU resources before, you'll need to do that now after the VM is shutdown. (See my other script: Allocate-GPUs-VM.ps1 )" -ForegroundColor Yellow
Show-DebugMessage "Script finished."
# SIG # Begin signature block
# MII9agYJKoZIhvcNAQcCoII9WzCCPVcCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCXCXlPuiKba9mq
# eRjg11I8NvotamfTRprxYpsNL7C+0qCCIrQwggXMMIIDtKADAgECAhBUmNLR1FsZ
# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu
# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy
# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv
# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD
# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH
# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD
# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV
# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70
# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1
# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3
# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK
# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg
# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj
# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7
# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ
# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn
# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c
# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF
# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx
# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8
# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY
# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2
# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY
# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al
# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk
# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggbuMIIE1qADAgECAhMzAAJMICk2
# qiaB0qgPAAAAAkwgMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDEwHhcNMjUwMTEwMTUyODU3WhcNMjUwMTEz
# MTUyODU3WjBsMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHV3lvbWluZzERMA8GA1UE
# BxMIU2hlcmlkYW4xGzAZBgNVBAoTElRoaW8gU29mdHdhcmUsIExMQzEbMBkGA1UE
# AxMSVGhpbyBTb2Z0d2FyZSwgTExDMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
# igKCAYEAhuCMMGQPXoM4mNkhlFGJOdWeXHNpVAtLP5x8zY4sUJMtfnADx+hKGpty
# dBCuaGUvQi0TFali8qbTbZEOHxTu7AoLOtIe8Qk0W4eA4Y8Ed6PaXq/tIFGJjjbz
# S9QqfPR6ilteDT4r03c2F/A34x1NXsKKq8puT8AQO8m57sCu4s+TR0Y36qxyGW9k
# rZEoIP5ADyJj+wmdJieGeQz8bkMqQnszdH6tsoS+Nf4v5rfubLKzr1qcPMNjacEQ
# Dczylx/dviee1ZgsmqZZdsvlm8VSbgYZbNleMeZxPI6FWU3tnv26XteIQrKeRE8S
# onGtjmR4BdTwwp5HWWCaTcHbmvvlzqbjsFDQGsDfiExOLcd3VtLs8JLdT+3jsfmV
# hTvxnnbct+fy7VEVuPsIOJ8X8NPxD4sgEXZSru1AJgn6BzA/F52BaoOAQFa4JsqI
# S9aGwvMebqG5GPW6aZinJG73V7bITW9/tppGIZNcjew2X0Y0xBrQ9S05ShQBaqQm
# jnzWUXv9AgMBAAGjggIZMIICFTAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIH
# gDA8BgNVHSUENTAzBgorBgEEAYI3YQEABggrBgEFBQcDAwYbKwYBBAGCN2GCyITf
# TKbD3mqByam9GIO77qlmMB0GA1UdDgQWBBTOZLZ3d0ebfYI4gH3lsVuuHv9AhzAf
# BgNVHSMEGDAWgBTog8Qz19yfDJx2mgqm1N+Hpl5Y7jBnBgNVHR8EYDBeMFygWqBY
# hlZodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQl
# MjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBBT0MlMjBDQSUyMDAxLmNybDCBpQYIKwYB
# BQUHAQEEgZgwgZUwZAYIKwYBBQUHMAKGWGh0dHA6Ly93d3cubWljcm9zb2Z0LmNv
# bS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIw
# QU9DJTIwQ0ElMjAwMS5jcnQwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vbmVvY3NwLm1p
# Y3Jvc29mdC5jb20vb2NzcDBmBgNVHSAEXzBdMFEGDCsGAQQBgjdMg30BATBBMD8G
# CCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3Mv
# UmVwb3NpdG9yeS5odG0wCAYGZ4EMAQQBMA0GCSqGSIb3DQEBDAUAA4ICAQAzyO7W
# VW5UlNeq16mlsFaKwoHtCQIPaB7hx2mM+4ADalTR/glRWUG3YqU6Lhgt4M60S5J1
# CRZ9xxOIni9W5tlgfg/hGNPPB2g9nsSs4JufNfVvbV6j4vrs0Apj+hz+cddbnb7A
# zNp28efMhVZFu2ZvhHbBeOcWAbwS2rs2fiSJ5h2zKLwS6Eb2xShRmA/tHqwCYVT4
# Ks1CVTaLdM33Vv+IRmdtjYxZlOZk/MBH1WN6YgawS5aoC6geLK7ZsGARQnRghENS
# I1DhhavxrB074HGn4+5jSMUJzSdqQWc2/fr5QL9TxLsvtIdHKDAjjP/VlR002AxX
# 4Fcd5Vl8FOAWF9rQPLmhKpLmR1/btEreDVTBuc41yS5+Ay3BoICnG3B4PFxI4mFi
# KWy6XoiNtBudLiav1LnSRV5FxzMyUeJ4p3FMhxhIpXMI1TbNdcie1DUHKnCxUcRu
# MIBa1JV66bJArJlcEIz/U/YV4LG4uLCMBMfpBqbULwY7B+VofbQnWiquZ0kJzMi1
# 65Ul9uIF+YzfVBT1lDJuoEFyUvAg91FB1Coi/LdrF5nYdfRo5TuA7NnP78S84X2k
# mplbqh+ELlUew1NHvP6jjlHBOR0FnV06e53WMFTxcOFiQglX2ASmyM6QZQ1BfbXL
# 2wfoOQnSbiYRtDn2DRtcEyxQw7+k1Kh0ZFPMjDCCBu4wggTWoAMCAQICEzMAAkwg
# KTaqJoHSqA8AAAACTCAwDQYJKoZIhvcNAQEMBQAwWjELMAkGA1UEBhMCVVMxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0
# IElEIFZlcmlmaWVkIENTIEFPQyBDQSAwMTAeFw0yNTAxMTAxNTI4NTdaFw0yNTAx
# MTMxNTI4NTdaMGwxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdXeW9taW5nMREwDwYD
# VQQHEwhTaGVyaWRhbjEbMBkGA1UEChMSVGhpbyBTb2Z0d2FyZSwgTExDMRswGQYD
# VQQDExJUaGlvIFNvZnR3YXJlLCBMTEMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
# ggGKAoIBgQCG4IwwZA9egziY2SGUUYk51Z5cc2lUC0s/nHzNjixQky1+cAPH6Eoa
# m3J0EK5oZS9CLRMVqWLyptNtkQ4fFO7sCgs60h7xCTRbh4DhjwR3o9per+0gUYmO
# NvNL1Cp89HqKW14NPivTdzYX8DfjHU1ewoqrym5PwBA7ybnuwK7iz5NHRjfqrHIZ
# b2StkSgg/kAPImP7CZ0mJ4Z5DPxuQypCezN0fq2yhL41/i/mt+5ssrOvWpw8w2Np
# wRANzPKXH92+J57VmCyapll2y+WbxVJuBhls2V4x5nE8joVZTe2e/bpe14hCsp5E
# TxKica2OZHgF1PDCnkdZYJpNwdua++XOpuOwUNAawN+ITE4tx3dW0uzwkt1P7eOx
# +ZWFO/Gedty35/LtURW4+wg4nxfw0/EPiyARdlKu7UAmCfoHMD8XnYFqg4BAVrgm
# yohL1obC8x5uobkY9bppmKckbvdXtshNb3+2mkYhk1yN7DZfRjTEGtD1LTlKFAFq
# pCaOfNZRe/0CAwEAAaOCAhkwggIVMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQD
# AgeAMDwGA1UdJQQ1MDMGCisGAQQBgjdhAQAGCCsGAQUFBwMDBhsrBgEEAYI3YYLI
# hN9MpsPeaoHJqb0Yg7vuqWYwHQYDVR0OBBYEFM5ktnd3R5t9gjiAfeWxW64e/0CH
# MB8GA1UdIwQYMBaAFOiDxDPX3J8MnHaaCqbU34emXljuMGcGA1UdHwRgMF4wXKBa
# oFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29m
# dCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUyMENBJTIwMDEuY3JsMIGlBggr
# BgEFBQcBAQSBmDCBlTBkBggrBgEFBQcwAoZYaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ1Ml
# MjBBT0MlMjBDQSUyMDAxLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29uZW9jc3Au
# bWljcm9zb2Z0LmNvbS9vY3NwMGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADPI
# 7tZVblSU16rXqaWwVorCge0JAg9oHuHHaYz7gANqVNH+CVFZQbdipTouGC3gzrRL
# knUJFn3HE4ieL1bm2WB+D+EY088HaD2exKzgm5819W9tXqPi+uzQCmP6HP5x11ud
# vsDM2nbx58yFVkW7Zm+EdsF45xYBvBLauzZ+JInmHbMovBLoRvbFKFGYD+0erAJh
# VPgqzUJVNot0zfdW/4hGZ22NjFmU5mT8wEfVY3piBrBLlqgLqB4srtmwYBFCdGCE
# Q1IjUOGFq/GsHTvgcafj7mNIxQnNJ2pBZzb9+vlAv1PEuy+0h0coMCOM/9WVHTTY
# DFfgVx3lWXwU4BYX2tA8uaEqkuZHX9u0St4NVMG5zjXJLn4DLcGggKcbcHg8XEji
# YWIpbLpeiI20G50uJq/UudJFXkXHMzJR4nincUyHGEilcwjVNs11yJ7UNQcqcLFR
# xG4wgFrUlXrpskCsmVwQjP9T9hXgsbi4sIwEx+kGptQvBjsH5Wh9tCdaKq5nSQnM
# yLXrlSX24gX5jN9UFPWUMm6gQXJS8CD3UUHUKiL8t2sXmdh19GjlO4Ds2c/vxLzh
# faSamVuqH4QuVR7DU0e8/qOOUcE5HQWdXTp7ndYwVPFw4WJCCVfYBKbIzpBlDUF9
# tcvbB+g5CdJuJhG0OfYNG1wTLFDDv6TUqHRkU8yMMIIHWjCCBUKgAwIBAgITMwAA
# AAc3jFuh2VuM1AAAAAAABzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQGEwJVUzEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTQwMgYDVQQDEytNaWNyb3Nv
# ZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWduaW5nIFBDQSAyMDIxMB4XDTIxMDQxMzE3
# MzE1NFoXDTI2MDQxMzE3MzE1NFowWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlm
# aWVkIENTIEFPQyBDQSAwMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# ALf3wAMoB8W6Po8QNOITSPG8/hKm1r0rvXUYAGsIwmWrtWOeCEGpeQK6SVovHCI9
# FgPpqcIsfIk0YLqvSRC2b0zKNmdVOgLRNU595r6t5ssGfUnsVXfqzzk6/rnWuhlY
# MCwPNC4UX/NgL60sMZmaQh/5Wk9PHZ+/hrdHF2FTSiTkZtYUqwI4w0ImdSYqv0qo
# g6Bzejxpk+YVyrNthO/THhVmAeMtFJTaltGdizzbmvJNK2xEXYjUvp0z/8bBEmVJ
# 625sl2Wh73MhCmCvOVgc90q+hLfFZW3Ynf6YwaXByPh8raGlABhOq0lqpoe/2hGX
# gw1JM/bjCjhmrCIGJ3p1JORNG9lP/20Kg796nYY/VCWFgAzWAv94t4sXFtVRC2lP
# sE6l08SwBXpQov5UR0o2loqQ3hP02wW9M0woi53PZ5jo2TypbrTDYaPdcMaOIrXC
# aCJNmz6LfbfgFflMDWg0SG3BGkGgcnJfaXGMFpn9GyeCBZ/wpmDFRtXpAgcQcskT
# ZBZB5rjFy1+jzF3L3hOOozK/bMgtzPCR0XXUeM1Y3fxcQZ0uRzq6N6YOkrbhD7Ia
# 6eyPypNXExvMjlpfGqn+jiXgFchuJcifVfmcQpWJmlOcr7SmCpNRSwZxAXw1sPlA
# M0FdL3C6egFcdhXPJ9L6aMrna90sGZnJCbs+0fku/QczAgMBAAGjggIOMIICCjAO
# BgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFOiDxDPX
# 3J8MnHaaCqbU34emXljuMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIB
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y
# eS5odG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwEgYDVR0TAQH/BAgwBgEB
# /wIBADAfBgNVHSMEGDAWgBTZQSmwDw9jbO9p1/XNKZ6kSGow5jBwBgNVHR8EaTBn
# MGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNy
# b3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAy
# MDIxLmNybDCBrgYIKwYBBQUHAQEEgaEwgZ4wbQYIKwYBBQUHMAKGYWh0dHA6Ly93
# d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSUQlMjBW
# ZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIwMjAyMS5jcnQwLQYIKwYB
# BQUHMAGGIWh0dHA6Ly9vbmVvY3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG
# 9w0BAQwFAAOCAgEAd/7rSyLZMC06eDX4ffb626UrC/DcDyI9vkwZ2Ri9wvHrUxmL
# Ph2VMTRvqzXmWvkc7vaBHAGSQ4hoxFsrczGrw+gYod5xFhbCFuGhoeIAeJ/6UT3n
# layuItSxu4yd5Dy0YTTh2Yi1ELZqxeFeiMbVBY7wZ4o2mfaCMbEkkD/IhzIz/dqY
# 0KxwRVhxg25JsfsjuiGp90Dd2Jm3X3sM0r50Jim5Ik4myYHCdS9E2ewcJrA75vtF
# 0bDznxYJ84S1amXRMlsMNdG35TngSqpG90mgjUE8/J7IWlGYa8VVOajYGI2mg0EJ
# vj9khKQRe0aJRAt5ZZX7i+ADhgraDXTzlq8fbwWU1wFXUxNq9CA5PPuctZCxkyys
# 5jRZ+pFQnOQXXTO8aA1kOGlKAkV3LAXkYbHJZO5FVz/syRjzl8I1CW589irfYhf/
# AehQzuG5Rrhq6IDKcl5LsAgtmeF3H8jIzw4amWADxhk1CDTLRW2ruUbRhtQzlhPX
# nQmobbjzA4Acnz4sb4ct7J+81B4CAv2LDkzMVbjEIv24GpnpqP1TSma7GWktJ85j
# sSqYPag3n4+XyfYCB13KdhdDh3FcHtypxF2vJKszA360Zf8MCqzUhZ96e4NG+OAH
# dTjQ5lretTC0LxeeCxutoun34UwnqBU/WfaW1KNoMZckxYOwZtH4DpZ0Xxgwggee
# MIIFhqADAgECAhMzAAAAB4ejNKN7pY4cAAAAAAAHMA0GCSqGSIb3DQEBDAUAMHcx
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBG
# BgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0
# aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMTA0MDEyMDA1MjBaFw0zNjA0MDEy
# MDE1MjBaMGMxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xNDAyBgNVBAMTK01pY3Jvc29mdCBJRCBWZXJpZmllZCBDb2RlIFNpZ25p
# bmcgUENBIDIwMjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCy8MCv
# GYgo4t1UekxJbGkIVQm0Uv96SvjB6yUo92cXdylN65Xy96q2YpWCiTas7QPTkGnK
# 9QMKDXB2ygS27EAIQZyAd+M8X+dmw6SDtzSZXyGkxP8a8Hi6EO9Zcwh5A+wOALNQ
# bNO+iLvpgOnEM7GGB/wm5dYnMEOguua1OFfTUITVMIK8faxkP/4fPdEPCXYyy8NJ
# 1fmskNhW5HduNqPZB/NkWbB9xxMqowAeWvPgHtpzyD3PLGVOmRO4ka0WcsEZqyg6
# efk3JiV/TEX39uNVGjgbODZhzspHvKFNU2K5MYfmHh4H1qObU4JKEjKGsqqA6Rzi
# ybPqhvE74fEp4n1tiY9/ootdU0vPxRp4BGjQFq28nzawuvaCqUUF2PWxh+o5/TRC
# b/cHhcYU8Mr8fTiS15kRmwFFzdVPZ3+JV3s5MulIf3II5FXeghlAH9CvicPhhP+V
# aSFW3Da/azROdEm5sv+EUwhBrzqtxoYyE2wmuHKws00x4GGIx7NTWznOm6x/niqV
# i7a/mxnnMvQq8EMse0vwX2CfqM7Le/smbRtsEeOtbnJBbtLfoAsC3TdAOnBbUkbU
# fG78VRclsE7YDDBUbgWt75lDk53yi7C3n0WkHFU4EZ83i83abd9nHWCqfnYa9qIH
# PqjOiuAgSOf4+FRcguEBXlD9mAInS7b6V0UaNwIDAQABo4ICNTCCAjEwDgYDVR0P
# AQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTZQSmwDw9jbO9p
# 1/XNKZ6kSGow5jBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRt
# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYD
# VR0jBBgwFoAUyH7SaoUqG8oZmAQHJ89QEE9oqKIwgYQGA1UdHwR9MHsweaB3oHWG
# c2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy
# MElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIw
# QXV0aG9yaXR5JTIwMjAyMC5jcmwwgcMGCCsGAQUFBwEBBIG2MIGzMIGBBggrBgEF
# BQcwAoZ1aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNy
# b3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZp
# Y2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3J0MC0GCCsGAQUFBzABhiFodHRwOi8v
# b25lb2NzcC5taWNyb3NvZnQuY29tL29jc3AwDQYJKoZIhvcNAQEMBQADggIBAH8l
# Kp7+1Kvq3WYK21cjTLpebJDjW4ZbOX3HD5ZiG84vjsFXT0OB+eb+1TiJ55ns0BHl
# uC6itMI2vnwc5wDW1ywdCq3TAmx0KWy7xulAP179qX6VSBNQkRXzReFyjvF2BGt6
# FvKFR/imR4CEESMAG8hSkPYso+GjlngM8JPn/ROUrTaeU/BRu/1RFESFVgK2wMz7
# fU4VTd8NXwGZBe/mFPZG6tWwkdmA/jLbp0kNUX7elxu2+HtHo0QO5gdiKF+YTYd1
# BGrmNG8sTURvn09jAhIUJfYNotn7OlThtfQjXqe0qrimgY4Vpoq2MgDW9ESUi1o4
# pzC1zTgIGtdJ/IvY6nqa80jFOTg5qzAiRNdsUvzVkoYP7bi4wLCj+ks2GftUct+f
# GUxXMdBUv5sdr0qFPLPB0b8vq516slCfRwaktAxK1S40MCvFbbAXXpAZnU20FaAo
# Dwqq/jwzwd8Wo2J83r7O3onQbDO9TyDStgaBNlHzMMQgl95nHBYMelLEHkUnVVVT
# UsgC0Huj09duNfMaJ9ogxhPNThgq3i8w3DAGZ61AMeF0C1M+mU5eucj1Ijod5O2M
# MPeJQ3/vKBtqGZg4eTtUHt/BPjN74SsJsyHqAdXVS5c+ItyKWg3Eforhox9k3Wgt
# WTpgV4gkSiS4+A09roSdOI4vrRw+p+fL4WrxSK5nMYIaDDCCGggCAQEwcTBaMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSswKQYD
# VQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENBIDAxAhMzAAJMICk2
# qiaB0qgPAAAAAkwgMA0GCWCGSAFlAwQCAQUAoF4wEAYKKwYBBAGCNwIBDDECMAAw
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIEIIN12ne7
# waKk6MI5EAPHwb3b8Rb3ZM78K+uBBJSb8BOUMA0GCSqGSIb3DQEBAQUABIIBgEyH
# uruVe+mLKPXJROLALS81/xeNTG9SA2YCu0lUV+1GRqLXE8iSCC8vZa8iTetJjBHE
# oU12Iw57wWxxpjTaOS1keAblOoDuUFtbDOtPECRuUKFb8p9UcF90/8lKtlthXyPC
# T1JwIDW5bkx7KOv2JoKebv+RGgb3Qpj8pHSBp5Z37bSwxjnC2TQcWFSiAc/Bpnys
# EOtTB+NH4qHpKsL09hAlWnNFxHHssuJV5X8lXbAav/eby7BKgrmcrQWiFAuL8dbo
# QhtfOydk2RD40ubHKvS9dOHgMlOr21lD+VkOGBgpWoaFvT3FuVHszxeVhXb0j89X
# 6TVLCW6tRM1X5mP2JOcW1THa4enLUWwwsTMJH6gNX2BsBEmLeaGdp5TG5rpeKcgI
# TqYX9T/4BM/egWq/0lKjRzRoe8DbSPu5FznM4Yn/zeekMjXoZhIAq0/4MYg9TAKu
# dAsyfctw7KfStLTp+KhUnA/FyO089az4QUGsKIav1z9KP0SJCPR2/fJQgtJeFqGC
# F4wwgheIBgorBgEEAYI3AwMBMYIXeDCCF3QGCSqGSIb3DQEHAqCCF2UwghdhAgED
# MQ8wDQYJYIZIAWUDBAIBBQAwggFgBgsqhkiG9w0BCRABBKCCAU8EggFLMIIBRwIB
# AQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCBdd3e1Jh2Q2AQsQvDCFiYY
# MXF7CaOit1guSLS7rp6llgIGZ2AOYv4DGBIyMDI1MDExMTAxMTMzNS4yNVowBIAC
# AfSggeCkgd0wgdoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# JTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsT
# HVRoYWxlcyBUU1MgRVNOOjQ1RDYtOTZDNS01RTYzMTUwMwYDVQQDEyxNaWNyb3Nv
# ZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDyAwggeCMIIF
# aqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcxCzAJ
# BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNV
# BAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZp
# Y2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTExMTkyMDQy
# MzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBD
# QSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnznUmP94MWf
# BX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omFio5DHC4R
# BcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhIkQRKe3Qx
# s8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQooTUL
# Fm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/pdoZkZZQ
# bxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqINGbmw5OI
# RC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQZH55ngI0
# Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFjrhc087qL
# JQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWYBunFGNv2
# 1Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liwkGdzPJYH
# gnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo27xjlLAH
# WW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1UdDwEB/wQE
# AwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vYr0np
# Ptk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93
# d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNV
# HSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNV
# HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGE
# BgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
# L2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3Ql
# MjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggrBgEFBQcB
# AQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24l
# MjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDANBgkq
# hkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5r+k77iB7
# 9cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl53DNt
# 4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2XMOZzY7YQ
# 0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ497m
# wYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYioXhq
# V2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4KGag42psw
# jybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFfEV9Hh/+C
# SxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/KgaXn0GxdH
# 8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88TwIf4R4Y
# ZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9Nc+Zo
# IAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7pmgAXVsw
# ggeWMIIFfqADAgECAhMzAAAANtk2HIkKLmuBAAAAAAA2MA0GCSqGSIb3DQEBDAUA
# MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# MjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAy
# MDIwMB4XDTI0MDIxNTIwMzU1NloXDTI1MDIxNTIwMzU1NlowgdoxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBB
# bWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjQ1RDYt
# OTZDNS01RTYzMTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0
# YW1waW5nIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AMVRjOq4Pw1/XckSJGtCIPKfBxvfxdteStsoS0mYNI3Ua9S4aFP4I7odpXldCjWy
# 2080pLk1oeiSW8mKisbdCiB95mzKneDCrQ9Q7BmmjMY6YCmcgWq57Ix3spgMz2jW
# ElBpMJj0KZ800TF0hIMAV7IGzVK1q93GwOyXJ9EpOS5W7MwRCA4+E6hpQK9qdTL0
# R7IXb5tWM4NlBRNY/UDea0kPB9bunHuXGxGrKWH1kOX/iPTE+mUm82yINdJ8mnxV
# q59M0W2PkxosNx103g1mLFkrwSssseRvzetcEFSZMLRCW+cGfKKPejDIwQBi1dkt
# xJd2yaGUZ/14sTWiOejZ1bSI0OJIz2pusXEJdNINZ4AJeaKjpvhmSX75lX/vQP6c
# Sjou/ZPxOrzN0W+kRSk+SwmP3oKSyg+eOgD7ZjC0n49F/5X5poRM5SQOdnUotM94
# B5JVr8prjV/R6uh1+6cDCVrvRiCF1rjHMDZeiKTLtrDjV4KKvuCNsiRrCzklSj6l
# iZgqi6fUOC2ybO5XmSiO+ZqFEXgDEvoR38u7Zv4deoii2US/vSmXwG4+DDbb/ybq
# B9UHbW9M1nG+a5nfufgvU6JNFY9OtzWm7faUq/qweAkByBq5Had4QF8HsK7g7cqX
# jEYJdaC3suEY/oH0dZk/PQI55MANzONT5AWEnAw8UOelAgMBAAGjggHLMIIBxzAd
# BgNVHQ4EFgQURv3FPF9eD8EzqAud/pYMv/zrj8MwHwYDVR0jBBgwFoAUa2koOjUv
# SGNAz3vYr0npPtk92yEwbAYDVR0fBGUwYzBhoF+gXYZbaHR0cDovL3d3dy5taWNy
# b3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIw
# VGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNybDB5BggrBgEFBQcBAQRtMGswaQYI
# KwYBBQUHMAKGXWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMv
# TWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0ElMjAy
# MDIwLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4G
# A1UdDwEB/wQEAwIHgDBmBgNVHSAEXzBdMFEGDCsGAQQBgjdMg30BATBBMD8GCCsG
# AQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVw
# b3NpdG9yeS5odG0wCAYGZ4EMAQQCMA0GCSqGSIb3DQEBDAUAA4ICAQCNNQNXPEy1
# kjtvE7be6NzaFhFXAo+0iialmqIxGZ2SS5aMuHOXZR09fVx1qFcK2+xxjd13E9Qr
# sMCk2Lrb55mz+PoemHCcwQw/Ym8ZISrLbGuOfhDO2M1EZUK/uB6D9dOesTVXW/XB
# uxudB+Qd4bRD0/u4zDlkwQqYLA95+eXiZoXSHISYWfoumIA4jrBTiiZ/J+MmBdUW
# G/USiA5/sp314gsYq2N4+Zm4kdjqcKRct4AmxbBYx+5jhLC8QFw/qgcKwylISzq6
# mJBCOoyyUQ2lix0zXlO2HcJKL2p+s03kJiBzDswTLHRM/82MGkqCFgGJrVbPDJsI
# MbyUwAJcPZV/SbyXu5w/e0IrB7qnDnsMxZQv30hY5zCYNNgm6fiSSTzNajeqCUp7
# CemsgSGOWNr5ymz2CSvez5+9mrN2cw54mvtZQFtv9B2ISDKJ7WDROZPGTJnkZnlY
# ZCtjPtj35d06ta7OrOiQ52kAHYbXAinXt5PaiMfMYEBBZx5/FDVFFxhExICAv2Vr
# D5ctA4lG58oXsTSNStvI+8xup75CpJN5yt6UiRG3TSQ28/9UPy1oKw5m5kxKYHPo
# rCR2I0sGl38i9PijjENFargKF6BWIOCrx9LgzAL0FjMjcOw/T0gEk1Hd++q+kdo/
# 5HGbJp+Mh0+XKoOTAOPXTOHP0lA9WP1c+jGCBsEwgga9AgEBMHgwYTELMAkGA1UE
# BhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp
# TWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjACEzMAAAA2
# 2TYciQoua4EAAAAAADYwDQYJYIZIAWUDBAIBBQCgggQaMBEGCyqGSIb3DQEJEAIP
# MQIFADAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8X
# DTI1MDExMTAxMTMzNVowLwYJKoZIhvcNAQkEMSIEIKCJYgQS/J73MooxGN/qCfjq
# ObFo/VxOthi28GyrAVi7MIG5BgsqhkiG9w0BCRACLzGBqTCBpjCBozCBoAQgNAPX
# UALSLiuMSaihE5V9nrIlyQG5RoN/1h/zzjLFH2UwfDBlpGMwYTELMAkGA1UEBhMC
# VVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWlj
# cm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjACEzMAAAA22TYc
# iQoua4EAAAAAADYwggLcBgsqhkiG9w0BCRACEjGCAsswggLHoYICwzCCAr8wggIo
# AgEBMIIBCKGB4KSB3TCB2jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQG
# A1UECxMdVGhhbGVzIFRTUyBFU046NDVENi05NkM1LTVFNjMxNTAzBgNVBAMTLE1p
# Y3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9yaXR5oiMKAQEw
# BwYFKw4DAhoDFQChpRo9LhNJ2Ri7S6lvNM8rDucM0qBnMGWkYzBhMQswCQYDVQQG
# EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylN
# aWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDANBgkqhkiG
# 9w0BAQUFAAIFAOssKwwwIhgPMjAyNTAxMTAyMzI2MDRaGA8yMDI1MDExMTIzMjYw
# NFowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA6ywrDAIBADAHAgEAAgIA8DAHAgEA
# AgIRhjAKAgUA6y18jAIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMC
# oAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAFnH8DWZ
# HyLs1Ee/ziZA4SI/wK1xeviny5knQuOnf6hWBYqZUXR4/TWRjd6rmhwNAG0Bp9qn
# 2EabwpK4ZYDvXnKrdzrQb7mVWX82zQQq+2C2mHvaiWkV63mQ+/o0oEafd0TRgLfr
# Z+KjaHMMwNyWPlGESHOGRfsWNp9+GL4wAYM7MA0GCSqGSIb3DQEBAQUABIICACmB
# 7ZPgLH3eMjgDR9MFIUDOUrdmekr5SiMGp7m1NA7HkMYbL/WqdEpMhHWAAJzNYviR
# LP2YqRjuOh9QKJNrTHk41C24j+UFC7h7X/MyNwUAhi6WPNl3x3MxPhK7b6r/7Fno
# /xFoV/wXyQPCkX3BROlgTCy6cUTtHosLHr3m5XV/muuLt/JeeMLlRqvqvKwReZPL
# U3ZZCOB6w4qyYXr77wes/Lu0D8FQ6dfcrnlsHD41pLK7GmgFvFFrq9M5pi4oxrAD
# 6l4DsxA3F1JQbQljhGAR7FRAxfZEslxh6F3BwhtddxfV7uFMxO7fPXdvFPgUR0KG
# 7lmUBgh7PBhLRKQFbYYg9wahFhJLqcp0O2vzf9uzVVzjaAbvLkWGRWXdxw6YjlqC
# 87XTdAjR+gJDO44nES/cwYD1y6DK2G3AiSXtAGgWzMMLS+VJhkvGfhan1v59HTQm
# gwsGrdw3tP1JwAfwTEhQbYgrCsamcyjnI2V8PuUw0e7X7IllRCam/idotROqHxRN
# p9n6A257U1zrK9IDse2iwO6uN++Q3Kv4nxsjMUgA3W0BCikot6aYxD4HBVKTh4zB
# aR0PshvM6NC15M4qS9GLpeFVi9osmf5iHKrDdLpaYC/h3+VMa7As56A8pGvR/yZw
# g4UZc3472SMnH3PnIkK2ovcqDqmetxP8Bz619TvW
# SIG # End signature block
@gsuns
Copy link

gsuns commented Dec 6, 2024

Hi
It was an honor to use your script after my editing. Scripts work fine.
I don't understand ps1 scripts. I just replaced nv_ with nvmii. because I'm a laptop NVIDIA 2080GPU.

Here's what my laptop graphics card outputs:

PS D:\> Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\nvlddmkm" | Select-Object ImagePath

ImagePath
---------
\SystemRoot\System32\DriverStore\FileRepository\nvmii.inf_amd64_085de2d4b49d7707\nvlddmkm.sys

If you can pop up a session and give the user the option to copy the driver starting with nv_ or nvmii.. If you update the script, the person using the nvmii. driver doesn't have to edit your script again.

Anyway, thanks to your script, he did help me. Thank you
Have a great day

@ThioJoe
Copy link
Author

ThioJoe commented Jan 11, 2025

@gsuns I've added support for the mobile driver folders.

Full list of changes in the latest version:

-Add support for mobile nvidia drivers (in nvmii folder)
-Add alternative method for copying zip file VM if first fails
-Better temporary GPU driver folder name
-Fixed Compress-Archive to work with PowerShell 5 when file in use
-Make parsed arguments case insensitive

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment