Toggle Smart Card Logon Requirement with Set-ScForceOption
Two-factor authentication with smart cards is becoming more common, but it can be a real pain when the computer is broken and Windows is refusing to allow a local account to logon for troubleshooting. The security setting Interactive logon: Require smart card
may prevent console logons, but if the registry can still be accessed over the network, this requirement can be toggled.
I’ve covered this same method in the past with a vbscript, and a PowerShell GUI, but this function is designed to work more like a traditional PowerShell cmdlet. The problem of bypassing a smart card requirement also comes up often enough for me that I decided it warranted an update.
PS>Set-ScForceOption -ComputerName Computer01 -Status
ComputerName Status
------------ ------
Computer01 Enabled
PS>Set-ScForceOption -ComputerName Computer01 -Disable
PS>Set-ScForceOption -ComputerName Computer01 -Status
ComputerName Status
------------ ------
Computer01 Disabled
PS>
Function Set-ScForceOption
{
[CmdletBinding(
SupportsShouldProcess=$true,
ConfirmImpact="Medium",
DefaultParameterSetname='Status'
)]
Param
(
[parameter(Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName,
[Parameter(
ParameterSetName='Status')]
[Switch]
$Status,
[Parameter(
ParameterSetName='Enable')]
[Switch]
$Enable,
[Parameter(
ParameterSetName='Disable')]
[Switch]
$Disable
)
Process
{
ForEach ($Computer in $ComputerName)
{
If (-NOT (Test-Connection -ComputerName $Computer -Count 1 -Quiet) )
{
Write-Warning "Unable to connect to $Computer"
Continue
}
Switch ($PsCmdlet.ParameterSetName)
{
'Status'
{
If ( $PSCmdlet.ShouldProcess($Computer, "Get status of ScForceOption") )
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system")
If ($regKey.GetValue("scforceoption") -eq 1)
{
Write-Output (New-Object -TypeName PSObject -Property @{
ComputerName=$Computer
Status='Enabled'})
}
Else
{
Write-Output (New-Object -TypeName PSObject -Property @{
ComputerName=$Computer
Status='Disabled'})
}
}
}
'Enable'
{
If ( $PSCmdlet.ShouldProcess($Computer, "Enable ScForceOption") )
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system", $true)
$regKey.SetValue("scforceoption", 1)
}
}
'Disable'
{
If ( $PSCmdlet.ShouldProcess($Computer, "Disable ScForceOption") )
{
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer)
$regKey = $reg.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system", $true)
$regKey.SetValue("scforceoption", 0)
}
}
}
}
}
}