User Account Control, also known as UAC, was designed to reduce vulnerability by requiring confirmation when system settings are being changed. Some people hate it, some don’t mind it. But most understand it’s intent.
In any case, when deploying servers, it’s key to know what state the UAC settings are in, so that we can script accordingly. Normally, I just set the registry value to whatever I need it to be, using a one-liner such as:
To disable UAC:
Set-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\system -Name EnableLUA -Value 0
To enable UAC:
Set-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\system -Name EnableLUA -Value 1
UAC changes how a token is assembled when you log on. If we’re making changes to this, remember that a reboot is required before the new setting takes effect.
But what if we just need to programmatically peek at what UAC is set to, so that we can act accordingly? Well, this handy little function should help:
function Get-UACStatus {
<#
.SYNOPSIS
Gets the current status of User Account Control (UAC) on a computer.
.DESCRIPTION
Gets the current status of User Account Control (UAC) on a computer. $true indicates UAC is enabled, $false that it is disabled.
.NOTES
Version : 1.0
Rights Required : Local admin on server
: ExecutionPolicy of RemoteSigned or Unrestricted
Author(s) : Pat Richard (pat@innervation.com)
Dedicated Post : https://www.ucunleashed.com/1026
Disclaimer : You running this script means you won't blame me if this breaks your stuff.
.EXAMPLE
Get-UACStatus
Description
-----------
Returns the status of UAC for the local computer. $true if UAC is enabled, $false if disabled.
.EXAMPLE
Get-UACStatus -Computer [computer name]
Description
-----------
Returns the status of UAC for the computer specified via -Computer. $true if UAC is enabled, $false if disabled.
.LINK
Functions: Get-UACStatus Set-UACStatus – PowerShell Functions for Getting and Setting UAC Status
.INPUTS
None. You cannot pipe objects to this script.
#Requires -Version 2.0
#>
[cmdletBinding(SupportsShouldProcess = $true)]
param(
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true, Mandatory = $false)]
[string]$Computer
)
[string]$RegistryValue = "EnableLUA"
[string]$RegistryPath = "Software\Microsoft\Windows\CurrentVersion\Policies\System"
[bool]$UACStatus = $false
$OpenRegistry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
$Subkey = $OpenRegistry.OpenSubKey($RegistryPath,$false)
$Subkey.ToString() | Out-Null
$UACStatus = ($Subkey.GetValue($RegistryValue) -eq 1)
write-host $Subkey.GetValue($RegistryValue)
return $UACStatus
} # end function Get-UACStatus
You can call it via
Get-UACStatus
to see the status for the local machine, and
Get-UACStatus -Computer [computer name]
to see the status of a remote machine. Full help is available via
Get-Help Get-UACStatus
And if we need a little function to deal with enabling or disabling, for building into deployment scripts, we have this one, which includes functionality for rebooting:
function Set-UACStatus {
<#
.SYNOPSIS
Enables or disables User Account Control (UAC) on a computer.
.DESCRIPTION
Enables or disables User Account Control (UAC) on a computer.
.NOTES
Version : 1.0
Rights Required : Local admin on server
: ExecutionPolicy of RemoteSigned or Unrestricted
Author(s) : Pat Richard (pat@innervation.com)
Dedicated Post : https://www.ucunleashed.com/1026
Disclaimer : You running this script means you won't blame me if this breaks your stuff.
.EXAMPLE
Set-UACStatus -Enabled [$true|$false]
Description
-----------
Enables or disables UAC for the local computer.
.EXAMPLE
Set-UACStatus -Computer [computer name] -Enabled [$true|$false]
Description
-----------
Enables or disables UAC for the computer specified via -Computer.
.LINK
Functions: Get-UACStatus Set-UACStatus – PowerShell Functions for Getting and Setting UAC Status
.INPUTS
None. You cannot pipe objects to this script.
#Requires -Version 2.0
#>
param(
[cmdletbinding()]
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true, Mandatory = $false)]
[string]$Computer = $env:ComputerName,
[parameter(ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
[bool]$enabled
)
[string]$RegistryValue = "EnableLUA"
[string]$RegistryPath = "Software\Microsoft\Windows\CurrentVersion\Policies\System"
$OpenRegistry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
$Subkey = $OpenRegistry.OpenSubKey($RegistryPath,$true)
$Subkey.ToString() | Out-Null
if ($enabled -eq $true){
$Subkey.SetValue($RegistryValue, 1)
}else{
$Subkey.SetValue($RegistryValue, 0)
}
$UACStatus = $Subkey.GetValue($RegistryValue)
$UACStatus
$Restart = Read-Host "`nSetting this requires a reboot of $Computer. Would you like to reboot $Computer [y/n]?"
if ($Restart -eq "y"){
Restart-Computer $Computer -force
Write-Host "Rebooting $Computer"
}else{
Write-Host "Please restart $Computer when convenient"
}
} # end function Set-UACStatus
Call it via
Set-UACStatus -Computer [computer name] -Enabled [$true|$false]
And, like Get-UACStatus, full help is available via
Get-Help Set-UACStatus
Donations
I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.
Follow Me