diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index 9605c2bc9..39803b46c 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -3,6 +3,7 @@ require "shellwords" require "tmpdir" require "vagrant/util/subprocess" +require "vagrant/util/powershell" module Vagrant module Util @@ -42,27 +43,17 @@ module Vagrant # Checks if the user running Vagrant on Windows has administrative # privileges. # + # From: https://support.microsoft.com/en-us/kb/243330 + # SID: S-1-5-19 + # # @return [Boolean] def windows_admin? return @_windows_admin if defined?(@_windows_admin) - # We lazily-load this because it is only available on Windows - require "win32/registry" - - # Verify that we have administrative privileges. The odd method of - # detecting this is based on this StackOverflow question: - # - # https://stackoverflow.com/questions/560366/ - # detect-if-running-with-administrator-privileges-under-windows-xp @_windows_admin = -> { - begin - Win32::Registry::HKEY_USERS.open("S-1-5-19") {} - - # The above doesn't seem to be 100% bullet proof. See GH-5616. - return (`reg query HKU\\S-1-5-19 2>&1` =~ /ERROR/).nil? - rescue Win32::Registry::Error - return false - end + ps_cmd = "[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { if ($_.Value -eq 'S-1-5-19'){ Write-Host 'true'; break }}" + output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd) + return output == 'true' }.call return @_windows_admin @@ -78,15 +69,13 @@ module Vagrant # @return [Boolean] def windows_hyperv_admin? return @_windows_hyperv_admin if defined?(@_windows_hyperv_admin) + @_windows_hyperv_admin = -> { - begin - username = ENV["USERNAME"] - process = Subprocess.execute("net", "localgroup", "Hyper-V Administrators") - return process.stdout.include?(username) - rescue Errors::CommandUnavailableWindows - return false - end + ps_cmd = "[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | ForEach-Object { if ($_.Value -eq 'S-1-5-32-578'){ Write-Host 'true'; break }}" + output = Vagrant::Util::PowerShell.execute_cmd(ps_cmd) + return output == 'true' }.call + return @_windows_hyperv_admin end diff --git a/lib/vagrant/util/powershell.rb b/lib/vagrant/util/powershell.rb index 7357d829d..ce65c6631 100644 --- a/lib/vagrant/util/powershell.rb +++ b/lib/vagrant/util/powershell.rb @@ -19,7 +19,9 @@ module Vagrant def self.execute(path, *args, **opts, &block) command = [ "powershell", + "-NoLogo", "-NoProfile", + "-NonInteractive", "-ExecutionPolicy", "Bypass", "&('#{path}')", args @@ -32,14 +34,37 @@ module Vagrant Subprocess.execute(*command, &block) end + # Execute a powershell command. + # + # @param [String] command PowerShell command to execute. + # @return [Subprocess::Result] + def self.execute_cmd(command) + c = [ + "powershell", + "-NoLogo", + "-NoProfile", + "-NonInteractive", + "-ExecutionPolicy", "Bypass", + "-Command", + command + ].flatten + + r = Subprocess.execute(*c) + return nil if r.exit_code != 0 + return r.stdout.chomp + end + # Returns the version of PowerShell that is installed. # # @return [String] def self.version command = [ "powershell", + "-NoLogo", "-NoProfile", + "-NonInteractive", "-ExecutionPolicy", "Bypass", + "-Command", "$PSVersionTable.PSVersion.Major" ].flatten