diff --git a/pkg/minikube/reason/reason.go b/pkg/minikube/reason/reason.go index 9cce8f1af000..d3602e59c442 100644 --- a/pkg/minikube/reason/reason.go +++ b/pkg/minikube/reason/reason.go @@ -232,6 +232,7 @@ var ( DrvNotDetected = Kind{ID: "DRV_NOT_DETECTED", ExitCode: ExDriverNotFound} DrvAsRoot = Kind{ID: "DRV_AS_ROOT", ExitCode: ExDriverPermission} DrvNeedsRoot = Kind{ID: "DRV_NEEDS_ROOT", ExitCode: ExDriverPermission} + DrvNeedsAdministrator = Kind{ID: "DRV_NEEDS_ADMINISTRATOR", ExitCode: ExDriverPermission} GuestCacheLoad = Kind{ID: "GUEST_CACHE_LOAD", ExitCode: ExGuestError} GuestCert = Kind{ID: "GUEST_CERT", ExitCode: ExGuestError} diff --git a/pkg/minikube/registry/drvs/hyperv/hyperv.go b/pkg/minikube/registry/drvs/hyperv/hyperv.go index c12f2d826dd0..a114842fc032 100644 --- a/pkg/minikube/registry/drvs/hyperv/hyperv.go +++ b/pkg/minikube/registry/drvs/hyperv/hyperv.go @@ -89,7 +89,7 @@ func status() registry.State { ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) defer cancel() - cmd := exec.CommandContext(ctx, path, "@(Get-Wmiobject Win32_ComputerSystem).HypervisorPresent") + cmd := exec.CommandContext(ctx, path, "-NoProfile", "-NonInteractive","@(Get-Wmiobject Win32_ComputerSystem).HypervisorPresent") out, err := cmd.CombinedOutput() if err != nil { @@ -105,5 +105,32 @@ func status() registry.State { return registry.State{Installed: false, Running: false, Error: errorMessage, Fix: fixMessage, Doc: docURL} } + // Ensure user is either a Windows Administrator or a Hyper-V Administrator. + adminCheckCmd := exec.CommandContext(ctx, path, "-NoProfile", "-NonInteractive",`@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")`) + adminCheckOut, adminCheckErr := adminCheckCmd.CombinedOutput() + + if adminCheckErr != nil { + errorMessage := fmt.Errorf("%s returned %q", strings.Join(adminCheckCmd.Args, " "), adminCheckOut) + fixMessage := "Unable to determine current user's administrator privileges" + return registry.State{Installed: true, Running: false, Error: errorMessage, Fix: fixMessage} + } + + hypervAdminCheckCmd := exec.CommandContext(ctx, path, "-NoProfile", "-NonInteractive", `@([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(([System.Security.Principal.SecurityIdentifier]::new("S-1-5-32-578")))`) + hypervAdminCheckOut, hypervAdminCheckErr := hypervAdminCheckCmd.CombinedOutput() + + if hypervAdminCheckErr != nil { + errorMessage := fmt.Errorf("%s returned %q", strings.Join(hypervAdminCheckCmd.Args, " "), hypervAdminCheckOut) + fixMessage := "Unable to determine current user's Hyper-V administrator privileges." + return registry.State{Installed: true, Running: false, Error: errorMessage, Fix: fixMessage} + } + + + if (strings.TrimSpace(string(adminCheckOut)) != "True") && (strings.TrimSpace(string(hypervAdminCheckOut)) != "True") { + err := fmt.Errorf("Hyper-V requires Administrator privileges") + fixMessage := "Right-click the PowerShell icon and select Run as Administrator to open PowerShell in elevated mode." + return registry.State{Installed: true, Running: false, Error: err, Fix: fixMessage} + } + + return registry.State{Installed: true, Healthy: true} -} +} \ No newline at end of file