Skip to content

Commit f8927a8

Browse files
committed
Support running PowerShell within Constrained Language Mode
1 parent 3d68e16 commit f8927a8

File tree

3 files changed

+21
-31
lines changed

3 files changed

+21
-31
lines changed

lib/vagrant/util/platform.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ def windows?
7171
# privileges.
7272
#
7373
# From: https://support.microsoft.com/en-us/kb/243330
74-
# SID: S-1-5-19
74+
# SID: S-1-5-32-544
75+
# Name: Administrators
7576
#
7677
# @return [Boolean]
7778
def windows_admin?
7879
return @_windows_admin if defined?(@_windows_admin)
79-
8080
@_windows_admin = -> {
81-
ps_cmd = '(new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)'
81+
ps_cmd = '$x = (Get-LocalGroupMember -SID "S-1-5-32-544" | where Name -eq $(Get-WMIObject -class Win32_ComputerSystem | select username).username); if ($x){ Write-Output "True"}'
8282
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
8383
return output == 'True'
8484
}.call
@@ -105,6 +105,13 @@ def windows_hyperv_admin?
105105
return @_windows_hyperv_admin = true
106106
end
107107

108+
ps_cmd = "$x = (Get-LocalGroupMember -SID 'S-1-5-32-578' | where Name -eq $(Get-WMIObject -class Win32_ComputerSystem | select username).username); if ($x){ Write-Output 'true'}"
109+
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
110+
return @_windows_hyperv_admin = true if output == "true"
111+
112+
# This won't work in constrained language mode, but there is no easy way to replicate.
113+
# Leaving it as is because the most likley two cases (user is in administrators or hyperv administrators group)
114+
# are already checked, so this script is unlikley to be required.
108115
ps_cmd = "Write-Output ([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | " \
109116
"Select-Object Value | ConvertTo-JSON)"
110117
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
@@ -115,16 +122,15 @@ def windows_hyperv_admin?
115122
[]
116123
end
117124
admin_group = groups.detect do |g|
118-
g["Value"].to_s == "S-1-5-32-578" ||
119-
(g["Value"].start_with?("S-1-5-21") && g["Value"].to_s.end_with?("-512"))
125+
g["Value"].start_with?("S-1-5-21") && g["Value"].to_s.end_with?("-512")
120126
end
121127

122128
if admin_group
123129
return @_windows_hyperv_admin = true
124130
end
125131
end
126132

127-
ps_cmd = "$x = (Get-VMHost).Name; if($x -eq [System.Net.Dns]::GetHostName()){ Write-Output 'true'}"
133+
ps_cmd = "if ((Get-VMHost).Name.StartsWith($env:computername)){ Write-Output 'true'}"
128134
output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd)
129135
result = output == "true"
130136

plugins/providers/hyperv/scripts/get_vm_status.ps1

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,14 @@ param(
55
[string]$VmId
66
)
77

8-
# Make sure the exception type is loaded
9-
try
10-
{
11-
# Microsoft.HyperV.PowerShell is present on all versions of Windows with HyperV
12-
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.HyperV.PowerShell, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
13-
# Microsoft.HyperV.PowerShell.Objects is only present on Windows >= 10.0, so this will fail, and we ignore it since the needed exception
14-
# type was loaded in Microsoft.HyperV.PowerShell
15-
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.HyperV.PowerShell.Objects, Culture=neutral, PublicKeyToken=31bf3856ad364e35')
16-
} catch {
17-
# Empty catch ok, since if we didn't load the types, we will fail in the next block
18-
}
19-
20-
$VmmsPath = if ([environment]::Is64BitProcess) { "$($env:SystemRoot)\System32\vmms.exe" } else { "$($env:SystemRoot)\Sysnative\vmms.exe" }
21-
$HyperVVersion = [version](Get-Item $VmmsPath).VersionInfo.ProductVersion
22-
23-
if($HyperVVersion -lt ([version]'10.0')) {
24-
$ExceptionType = [Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException]
25-
} else {
26-
$ExceptionType = [Microsoft.HyperV.PowerShell.VirtualizationException]
27-
}
288
try {
299
$VM = Hyper-V\Get-VM -Id $VmId -ErrorAction "Stop"
3010
$State = $VM.state
3111
$Status = $VM.status
3212
} catch [Exception] {
33-
if($_.Exception.GetType() -eq $ExceptionType)
13+
# "ObjectNotFound" when Hyper-V >= 10 (Microsoft.HyperV.PowerShell.VirtualizationException)
14+
# "NotSpecified" when Hyper-V < 10 (Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException)
15+
if(("ObjectNotFound", "NotSpecified") -Contains $_.Exception.ErrorCategory)
3416
{
3517
$State = "not_created"
3618
$Status = $State

plugins/providers/hyperv/scripts/utils/VagrantVM/VagrantVM.psm1

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Always stop when errors are encountered unless instructed not to
22
$ErrorActionPreference = "Stop"
3-
43
# Vagrant VM creation functions
54

65
function New-VagrantVM {
@@ -18,7 +17,7 @@ function New-VagrantVM {
1817
[parameter(Mandatory=$false)]
1918
[string] $VMName
2019
)
21-
if([IO.Path]::GetExtension($VMConfigFile).ToLower() -eq ".xml") {
20+
if($VMConfigFile.EndsWith(".xml", "CurrentCultureIgnoreCase")) {
2221
return New-VagrantVMXML @PSBoundParameters
2322
} else {
2423
return New-VagrantVMVMCX @PSBoundParameters
@@ -85,6 +84,7 @@ function New-VagrantVMVMCX {
8584
VhdDestinationPath = Join-Path $DataPath "Virtual Hard Disks";
8685
VirtualMachinePath = $DataPath;
8786
}
87+
8888
$VMConfig = (Hyper-V\Compare-VM -Copy -GenerateNewID @NewVMConfig -ErrorAction SilentlyContinue)
8989

9090
# If the config is empty it means the import failed. Attempt to provide
@@ -122,7 +122,7 @@ function New-VagrantVMVMCX {
122122
}
123123
foreach($Controller in $Controllers) {
124124
foreach($Drive in $Controller.Drives) {
125-
if([System.IO.Path]::GetFileName($Drive.Path) -eq [System.IO.Path]::GetFileName($SourcePath)) {
125+
if((Split-Path -Leaf $Drive.Path) -eq (Split-Path -Leaf $SourcePath)) {
126126
$Path = $Drive.Path
127127
Hyper-V\Remove-VMHardDiskDrive $Drive
128128
Hyper-V\New-VHD -Path $DestinationPath -ParentPath $SourcePath -Differencing
@@ -729,8 +729,10 @@ function Check-VagrantHyperVAccess {
729729
[string] $Path
730730
)
731731
$acl = Get-ACL -Path $Path
732+
$systemAccount = [wmi]"Win32_SID.SID='S-1-5-18'"
733+
$localisedAccount = $systemAccount.ReferencedDomainName + "\" + $systemAccount.AccountName
732734
$systemACL = $acl.Access | where {
733-
try { return $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value -eq "S-1-5-18" } catch { return $false } -and
735+
$_.IdentityReference.Value -eq $localisedAccount -and
734736
$_.FileSystemRights -eq "FullControl" -and
735737
$_.AccessControlType -eq "Allow" -and
736738
$_.IsInherited -eq $true}

0 commit comments

Comments
 (0)