-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrite-rdp-file.ps1
More file actions
124 lines (109 loc) · 4.58 KB
/
Copy pathwrite-rdp-file.ps1
File metadata and controls
124 lines (109 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
$ErrorActionPreference = "Stop"; $scriptArgs = $args
function ArgValue($name) {
for ($i = 0; $i -lt $scriptArgs.Count; $i++) {
if ($scriptArgs[$i] -in @("-$name", "--$name")) { return $scriptArgs[$i + 1] }
}
return ""
}
function FullPath($path) {
$path = [Environment]::ExpandEnvironmentVariables([string]$path)
if ($path -match '^~[\\/](.*)$') { return (Join-Path $HOME $Matches[1]) }
if ([IO.Path]::IsPathRooted($path)) { return $path }
return (Join-Path $PSScriptRoot $path)
}
function Default($cfg, $name, $value) {
if ($null -eq $cfg.$name) { $cfg | Add-Member -Force NoteProperty $name $value }
}
function AdapterIPv4Addresses($adapter) {
@($adapter.IPAddresses |
Where-Object { $_ -match '^\d+\.\d+\.\d+\.\d+$' -and $_ -notlike '169.254.*' -and $_ -ne '0.0.0.0' })
}
function CurrentRdpIPv4($path) {
if (-not (Test-Path -LiteralPath $path)) { return "" }
$line = Get-Content -LiteralPath $path |
Where-Object { $_ -match '^full address:s:' } |
Select-Object -First 1
$match = [regex]::Match([string]$line, '^full address:s:(\d+\.\d+\.\d+\.\d+):3389$')
if ($match.Success) { return $match.Groups[1].Value }
return ""
}
function RdpTarget($vmName, $path) {
$adapters = @(Get-VMNetworkAdapter -VMName $vmName -ErrorAction Stop)
$allAddresses = @($adapters | ForEach-Object { AdapterIPv4Addresses $_ } | Sort-Object -Unique)
if ($allAddresses.Count -eq 0) { throw "No usable VM IPv4 address found for '$vmName'." }
$managementAddresses = @(
foreach ($adapter in $adapters) {
if ([string]$adapter.DeviceNaming -ne "On" -or [string]::IsNullOrWhiteSpace([string]$adapter.SwitchName)) {
continue
}
$switch = Get-VMSwitch -Name $adapter.SwitchName -ErrorAction SilentlyContinue
if ($null -eq $switch -or [string]$switch.SwitchType -ne "Internal" -or -not [bool]$switch.AllowManagementOS) {
continue
}
AdapterIPv4Addresses $adapter
}
)
$managementAddresses = @($managementAddresses | Sort-Object -Unique)
$currentAddress = CurrentRdpIPv4 $path
if (-not [string]::IsNullOrWhiteSpace($currentAddress) -and $managementAddresses -contains $currentAddress) {
return [pscustomobject]@{ Address = $currentAddress; Source = "management link" }
}
if ($managementAddresses.Count -eq 1) {
return [pscustomobject]@{ Address = $managementAddresses[0]; Source = "management link" }
}
if ($managementAddresses.Count -gt 1) {
throw "Multiple enabled management links were detected for '$vmName': $($managementAddresses -join ', ')."
}
if (-not [string]::IsNullOrWhiteSpace($currentAddress) -and $allAddresses -contains $currentAddress) {
return [pscustomobject]@{ Address = $currentAddress; Source = "existing profile" }
}
return [pscustomobject]@{ Address = $allAddresses[0]; Source = "VM network" }
}
function AvRdpProperties($cfg) {
if ($null -eq $cfg.avRedirection -or -not [bool]$cfg.avRedirection.enabled) { return @() }
@(
"audiocapturemode:i:1"
"camerastoredirect:s:*"
)
}
function SameLines($left, $right) {
if ($left.Count -ne $right.Count) { return $false }
return $null -eq (Compare-Object -ReferenceObject $left -DifferenceObject $right -SyncWindow 0)
}
$configPath = ArgValue "config"
if ([string]::IsNullOrWhiteSpace($configPath)) {
throw "Usage: .\write-rdp-file.ps1 --config config\windows.json"
}
$cfg = Get-Content -Raw (FullPath $configPath) | ConvertFrom-Json
@{
vmName = "WorkstationW11"
user = "work"
baseDir = "~/VMs/WorkstationW11"
}.GetEnumerator() | ForEach-Object { Default $cfg $_.Key $_.Value }
$baseDir = FullPath $cfg.baseDir
New-Item -ItemType Directory -Force -Path $baseDir | Out-Null
$path = Join-Path $baseDir "$($cfg.vmName).rdp"
$target = RdpTarget $cfg.vmName $path
$ip = $target.Address
$avProperties = @(AvRdpProperties $cfg)
$expected = @(
"full address:s:${ip}:3389"
"username:s:$($cfg.user)"
"prompt for credentials:i:1"
"screen mode id:i:2"
"use multimon:i:1"
"session bpp:i:32"
"redirectclipboard:i:1"
"audiomode:i:0"
$avProperties
"authentication level:i:2"
"enablecredsspsupport:i:1"
)
$current = if (Test-Path -LiteralPath $path) { @(Get-Content -LiteralPath $path) } else { @() }
if (SameLines $current $expected) {
Write-Host "Already configured: RDP profile $path"
} else {
$expected | Set-Content -LiteralPath $path -Encoding ascii
Write-Host "Configured: RDP profile $path"
}
Write-Host "RDP target: $($target.Source) $ip"