SCCM – Enabling ‘Easy’ Local Login on Domain Computers During OSD Part 2 of 2: Applying The Info

Hello folks!

Link to Part 1: SCCM – Enabling ‘Easy’ Local Login on Domain Computers During OSD Part 1 of 2: Getting The Info

In my organization we have need for the occasional machine to be configured with local login for such things as display computers or book sign-out machines in a library.  Local login is easy, but having to revisit the machine after imaging to set it up is annoying and, frankly, a waste of time.  Unfortunately we hadn’t been successful or too interested in solving this.  Until now that is.

WARNING: This will be highly specific (yet generalized) to our implementation.  It is my hope that somehow you find some use out of this.

Part 1 will cover getting the info at the start of your task sequence while Part 2 will cover the application of the info to the machine.

Credit where credit is due: https://www.scconfigmgr.com/2014/06/06/prompt-for-ou-location-during-osd-with-powershell/ was where the start of this all came from.

Here we go…

The code (Set-LocalUserInfo.ps1)….

Import-Module -name .\policyfileeditor.psm1

$u2 = New-Object -COMObject Microsoft.SMS.TSEnvironment
$u = $u2.Value("LocalUserName")

$l2 = New-Object -COMObject Microsoft.SMS.TSEnvironment
$l = $l2.Value("LocalUserLocation")

# Set simple password of username x2 if username is short
if ($u -ne "long user name")
{
 $pass = $u + $u
}
else
{
 $pass = $u
}

$n = switch ($l)
{
 "A location" {"123"}
 "Another location" {"456"}
 "One more" {"789"}
}

# Website variable to be set
$website = "https://mywebsite.whatev?page=" + $n

# Create the local user
NET USER $u $pass /ADD /expires:never

# Set the above local user to not have an expiring password
Get-WmiObject Win32_UserAccount -filter "LocalAccount=True"|?{$_.name -eq $u} |Set-WmiInstance -Arguments @{PasswordExpires=$false}

# Create registry keys for local login
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "DefaultUserName" -PropertyType "String" -Value $u
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "DefaultPassword" -PropertyType "String" -Value $pass
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "DefaultDomainName" -PropertyType "String" -Value '.\'
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoAdminLogon" -PropertyType "String" -Value '1'

Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoLogonSID"

# If this computer is going to be for display, we don't want to show a website automatically when it logs on
# However, if the other alternative is a book lookup website, then we do want to fire up IE on login
if ($u -ne "display computer or whatever")
{
 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "IEXPLORE" -PropertyType "String" -Value '"C:\Program Files\Internet Explorer\iexplore.exe"'
}

# Set the power scheme to High Performance on logon to ensure the system stays on (which we want in this case)
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "SetMaximumPower" -PropertyType "String" -Value "C:\Windows\System32\powercfg.exe /SETACTIVE 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"

# Specify local group policy file locations
$UserDir = "C:\windows\system32\GroupPolicy\User\registry.pol"
$MachineDir = "C:\windows\system32\GroupPolicy\Machine\registry.pol"

# Specify variables for setting screen saver (user setting)
$ScrnSvrPath = 'Software\Policies\Microsoft\Windows\Control Panel\Desktop';
$ScrnSvrName = 'SCRNSAVE.EXE'
$ScrnSvrData = 'scrnsave.scr'
$ScrnSvrType = 'String'
$ScrnSvrTimeoutName = 'ScreenSaveTimeOut'
$ScrnSvrTimeoutData = '120'

# Specify variables for disabling password prompt on computer wake (machine setting)
$RegPath = 'Software\Policies\Microsoft\Power\PowerSettings\0e796bdb-100d-47d6-a2d5-f7d2daa51f51'
$RegName = 'ACSettingIndex'
$RegName2 = 'DCSettingIndex'
$RegData = '0'
$RegType = 'DWord'

# Write settings to the local group policy
Set-PolicyFileEntry -Path $MachineDir -Key $RegPath -ValueName $RegName -Data $RegData -Type $RegType
Set-PolicyFileEntry -Path $MachineDir -Key $RegPath -ValueName $RegName2 -Data $RegData -Type $RegType

# Force a specific screen saver
# Sets screensaver to blank
# ONLY IF THE LOCAL USER IS *NOT* A DISPLAY USER
if ($u -ne "display")
{
 #Set screen saver to blank
 Set-PolicyFileEntry -Path $UserDir -Key $ScrnSvrPath -ValueName $ScrnSvrName -Data $ScrnSvrData -Type $ScrnSvrType
 
 #Set screen saver timeout to 2 minutes (120 seconds)
 Set-PolicyFileEntry -Path $UserDir -Key $ScrnSvrPath -ValueName $ScrnSvrTimeoutName -Data $ScrnSvrTimeoutData -Type $ScrnSvrType
}

# Prevent power plan turning off display after x minutes
# Sets value (in seconds) to 0 (disabled)
# ONLY IF THE LOCAL USER IS A DISPLAY USER
if ($u -eq "display")
{
 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "AC_TurnOffDisplayAfter" -PropertyType "String" -Value "C:\Windows\System32\powercfg.exe -setacvalueindex 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 7516b95f-f776-4464-8c53-06167f40cc99 3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e 0"
 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "DC_TurnOffDisplayAfter" -PropertyType "String" -Value "C:\Windows\System32\powercfg.exe -setdcvalueindex 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c 7516b95f-f776-4464-8c53-06167f40cc99 3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e 0"
}

# Load ntuser.dat (default user)
reg load "HKEY_LOCAL_MACHINE\defuser" "C:\users\default\ntuser.dat"
# Create a new key to control local user website, close the handle, and trigger garbage collection
Set-ItemProperty -Path "HKLM:\defuser\SOFTWARE\Microsoft\Internet Explorer\Main" -Name "Start Page" -Value $website
[gc]::Collect()
#Unload ntuser.dat
reg unload "HKEY_LOCAL_MACHINE\defuser"

 

It is ugly, I know.  Truth be told, I’m hacking and slashing my way to a working solution just like I do in C# and after it works you don’t really want to mess with it.

Part of the code above is setting local group policy options that were, for one reason or another, difficult or otherwise impossible to set programmatically.  I found http://brandonpadgett.com/powershell/Local-gpo-powershell/ which pointed me to a module that would allow me to set local group policy objects using Powershell.  Highly recommended and without the module my script would have been sunk and half-done.

Save the script in the same location as the script from Part 1 and include the Powershell module accessible from the above link in there as well.  Oh, as with the SConfigMgr link above, include the ServiceUI.exe executable from MDT.  My folder ended up looking like this:

folder

Add a “Run Powershell Script” step to the end of your task sequence and configure:

settsstep

and

settsstepsettings

Presto!

So far it is working flawlessly in my Windows 8.1 deployment and am in the process of testing for Windows 10.

Advertisements

One thought on “SCCM – Enabling ‘Easy’ Local Login on Domain Computers During OSD Part 2 of 2: Applying The Info

  1. Pingback: SCCM – Enabling ‘Easy’ Local Login on Domain Computers During OSD Part 1 of 2: Getting The Info | SASK IT GUY

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s