3

I want to force the same lock screen image on every user. I selected the image I want with group policy Local Computer Policy > Computer Configuration > Administrative Templates > Control Panel > Personalization > Force a specific default lock screen and logon image

When that didn't work, I used this to change registry values.

function Set-MachinePermissions {
    $RegistryPathPersonalization = 'HKLM:\Software\Policies\Microsoft\Windows\Personalization'

    If (-NOT (Test-Path $RegistryPathPersonalization)) {
        New-Item -Path $RegistryPathPersonalization -Force
    }

    New-ItemProperty -Path $RegistryPathPersonalization -Name 'LockScreenImage' -Value 'C:\Windows\Web\CSImages\LockScreen.jpg' -PropertyType 'String'
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'LockScreenOverlaysDisabled' -Value '1' -PropertyType 'DWORD'
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'NoChangingLockScreen' -Value '1' -PropertyType 'DWORD'
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'NoLockScreenSlideshow' -Value '1' -PropertyType 'DWORD'
}

Set-MachinePermissions

Even that did not change the lock screen. It still seems to use spotlight even after I disabled all spotlight features using group policy.

Here is the full PowerShell script I used to set up a fresh installation of Windows. I tested this in a VMWare virtual machine. You obviously need to run the script as admin.

Note: "BCCS" is the name of the local admin account that was created during installation!

Note: This also prints instructions to change the lock screen manually which works. But I want to automate it. You will need to log into the student account but not change the lock screen.

# Function to get and confirm password from user.
function Get-Password {
    param (
        [string]$UserName
    )
    # Get the password for user.
    while (-Not ($Match)) {
        # Read the password from user input as a secure string.
        Write-Host "Enter $UserName password:"
        $Password = Read-Host -AsSecureString
        # Read the password confirmation from user input and save as a secure string.
        Write-Host "Confirm $UserName password:"
        $Confirm = Read-Host -AsSecureString

        # Convert password and confirmation to plaintext.
        $PasswordText = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password))
        $ConfirmText = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Confirm))

        # Check if password and confirmation match
        if (($PasswordText -ceq $ConfirmText) -and (($PasswordText -or $ConfirmText) -ne '')) {
            $Match = $True
            return $Password
        }

        # If the password and confirmation don't match, run the loop till they do.
        else {
            Write-Host "Passwords do not match. Please enter them again."
            $Match = $False
        }
    }
}




# Function to get user input needed to run the script.
function Get-Info {
    # Get the password for BCCS user.
    $script:BCCSPassword = Get-Password -UserName 'BCCS'

    # Get the password for Student user.
    $script:StudentPassword = Get-Password -UserName 'Student'

    # Get the hostname (computer name) for the computer.
    Write-Host "Enter ComputerName:"
    $script:ComputerName = Read-Host
}




# Function to create drive to access user registry.
function New-UsersRegistryDrive {
    # Create a new object with the user profile of the user "Student".
    $StudentAcc = New-Object System.Security.Principal.NTAccount('Student')

    # Get the security identifier of the user "Student".
    $script:StudentSID = $StudentAcc.Translate([System.Security.Principal.SecurityIdentifier])

    # Create a new drive that gives us access to the registry of all users.
    New-PSDrive -Name 'HKU' -PSProvider 'Registry' -Root 'HKEY_USERS' -Scope 'script'
}




# Function to change the registry to set user permissions.
function Set-UserPermissions {
    # Get the present working directory.
    $WorkingDirectory = Get-Location

    # Set the location of CSImages folder.
    $ImageSource = "$WorkingDirectory\CSImages"

    # Set the destinations to where the CSImages folder should be copied.
    $ImageDestination = "$env:USERPROFILE\Pictures\CSImages", 'C:\Users\Student\Pictures\CSImages', 'C:\Windows\Web\CSImages'

    # Copy the CSImages folder to the destinations.
    foreach ($i in $ImageDestination) {
        Copy-Item -Path $ImageSource -Destination $i -Recurse -Force
    }

    # Print instructions to change the lock screen. Logging into the "Student" account also is essential as it will load the registry for that users, allowing us to change it.
    Write-Host 'Set the lock screen for BCCS account. It is located in the Pictures folder.'
    Write-Host 'Log into Student account and similarly set the lock screen'
    Write-Host 'Log back into BCCS account and press enter. Do NOT sign out of Student account! Use Win + L to lock screen.'

    # Continue when user presses any key.
    Write-Host -NoNewLine "Press any key to continue..."
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

    # Change the desktop wallpaper of current user.
    Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop' -Name 'WallPaper' -Value 'C:\Windows\Web\CSImages\Background.jpg'

    # Create the registry path to needed to disable Windows Spotlight if it doesn't exist.
    if (-Not (Test-Path 'HKCU:\Software\Policies\Microsoft\Windows\CloudContent')) {
        New-Item -Path 'HKCU:\Software\Policies\Microsoft\Windows\CloudContent' -Force
    }

    # Disalble Windows Spotlight features for user "BCCS".
    New-ItemProperty -Path 'HKCU:\Software\Policies\Microsoft\Windows\CloudContent' -Name 'DisableWindowsSpotlightFeatures' -Value '1' -PropertyType 'DWORD'

    # Create drive to access user registry.
    New-UsersRegistryDrive

    # Set the registry paths that we need to change to variables.
    $RegistryPathPolicies = "HKU:\$StudentSID\Software\Microsoft\Windows\CurrentVersion\Policies"
    $RegistryPathRSD = "HKU:\$StudentSID\Software\Policies\Microsoft\Windows\RemovableStorageDevices"
    $RegistryPathCloudContent = "HKU:\$StudentSID\Software\Policies\Microsoft\Windows\CloudContent"

    # Set the registry keys that we need to change to an array.
    $Keys = 'Explorer', 'ActiveDesktop', 'System'

    # Create registry keys if they are missing.
    foreach ($i in $Keys) {
        if (-Not (Test-Path "$RegistryPathPolicies\$i")) {
            New-Item -Path "$RegistryPathPolicies\$i" -Force
        }
    }

    # Create registry keys if they are missing.
    if (-Not (Test-Path $RegistryPathRSD)) {
        New-Item -Path $RegistryPathRSD -Force
    }

    # Create registry keys if they are missing.
    if (-Not (Test-Path $RegistryPathCloudContent)) {
        New-Item -Path $RegistryPathCloudContent -Force
    }

    # Disable Control Panel access by user "Student".
    New-ItemProperty -Path "$RegistryPathPolicies\Explorer" -Name 'NoControlPanel' -Value '1' -PropertyType 'DWORD'

    # Disable changing wallpaper by user "Student".
    New-ItemProperty -Path "$RegistryPathPolicies\ActiveDesktop" -Name 'NoChangingWallPaper' -Value '1' -PropertyType 'DWORD'

    # Set the wallpaper of user "Student".
    New-ItemProperty -Path "$RegistryPathPolicies\System" -Name 'Wallpaper' -Value 'C:\Windows\Web\CSImages\Background.jpg' -PropertyType 'String'

    # Set the wallpaper style to "Fit".
    New-ItemProperty -Path "$RegistryPathPolicies\System" -Name 'WallpaperStyle' -Value '4' -PropertyType 'DWORD'

    # Disable changing locations of personal directories (Desktop, Documents, Downloads, Picures, Videos, etc...)  by user "Student".
    New-ItemProperty -Path "$RegistryPathPolicies\Explorer" -Name 'DisablePersonalDirChange' -Value '1' -PropertyType 'DWORD'

    # Disable access to removable storage media  by user "Student".
    New-ItemProperty -Path $RegistryPathRSD -Name 'Deny_All' -Value '1' -PropertyType 'DWORD'

    # Disable Windows Spotlight features for user "Student.
    New-ItemProperty -Path $RegistryPathCloudContent -Name 'DisableWindowsSpotlightFeatures' -Value '1' -PropertyType 'DWORD'
}




# Function to create, modify and set permissions of users.
function Set-Users {
    # If the user "BCCS" doesn't exist,
    if (-Not (Get-LocalUser -Name 'BCCS')) {
        # Rename the current user to "BCCS".
        Rename-LocalUser -Name $env:USERNAME -NewName 'BCCS'
    }

    # Modify the user "BCCS" with the password taken from user input and add necessary permissions.
    Set-LocalUser -Name 'BCCS' -Password $BCCSPassword -FullName 'BCCS' -Description 'Main admin account of BCCS.' -AccountNeverExpires -PasswordNeverExpires $True -UserMayChangePassword $True

    # If the user "Student" doesn't exist,
    if (-Not (Get-LocalUser -Name 'Student')) {
        # Create the new user "Student" with the password taken from user input with necessary permissions.
        New-LocalUser -Name 'Student'
    }

    # Modify the user "Student" with the password taken from user input and add necessary permissions.
    Set-LocalUser -Name 'Student' -Password $StudentPassword -FullName 'Student' -Description 'Student account with low privileges.' -AccountNeverExpires -PasswordNeverExpires $True -UserMayChangePassword $False

    # Add the user "Student" to the localgroup "Users".
    Add-LocalGroupMember -Group 'Users' -Member 'Student'

    # Change the registry to set user permissions.
    Set-UserPermissions

    # Remove the user "Student" from the localgroup "Users".
    Remove-LocalGroupMember -Group 'Users' -Member 'Student'

    # Add the user "Student" to the localgroup "Guests".
    Add-LocalGroupMember -Group 'Guests' -Member 'Student'
}




# Function to change the registry to set machine permissions.
function Set-MachinePermissions {
    # Set the registry key that we need to change to a variable.
    $RegistryPathPersonalization = 'HKLM:\Software\Policies\Microsoft\Windows\Personalization'

    # If the registry key we need doesn't exist, create it.
    if (-NOT (Test-Path $RegistryPathPersonalization)) {
        New-Item -Path $RegistryPathPersonalization -Force
    }

    # Set the default lock screen image.
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'LockScreenImage' -Value 'C:\Windows\Web\CSImages\LockScreen.jpg' -PropertyType 'String'

    # Disable overlays on the lock screen.
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'LockScreenOverlaysDisabled' -Value '1' -PropertyType 'DWORD'

    # Prevent changing of the lock screen.
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'NoChangingLockScreen' -Value '1' -PropertyType 'DWORD'

    # Prevent using slideshow in lock screen.
    New-ItemProperty -Path $RegistryPathPersonalization -Name 'NoLockScreenSlideshow' -Value '1' -PropertyType 'DWORD'
}




# Function to rename the computer.
function Set-ComputerName {
    # Set the hostname (computer name) to the name taken from user input.
    Rename-Computer -NewName $ComputerName    
}




# Function to undo registry changes.
function Undo-RegistryChanges {
    # Create drive to access user registry.
    New-UsersRegistryDrive

    # Change the desktop wallpaper of current user to default value.
    Set-ItemProperty -Path 'HKCU:\Control Panel\Desktop\' -Name 'WallPaper' -Value 'C:\Windows\web\wallpaper\Windows\img0.jpg'

    # Set the registry keys that need to be deleted to a variable.
    $DeleteRegistryKeys = 'HKCU:\Software\Policies\Microsoft\Windows\CloudContent\', "HKU:\$StudentSID\Software\Microsoft\Windows\CurrentVersion\Policies\", "HKU:\$StudentSID\Software\Policies\Microsoft\Windows\CloudContent\", "HKU:\$StudentSID\Software\Policies\Microsoft\Windows\RemovableStorageDevices", 'HKLM:\Software\Policies\Microsoft\Windows\Personalization'
    
    # Delete the registry keys.
    Remove-Item -Path $DeleteRegistryKeys
}




# Function to set up the computer.
function Invoke-ComputerSetup {
    # Get user input needed to run the script.
    Get-Info

    # Clear the screen.
    Clear-Host

    # Create, modify and set permissions of users.
    Set-Users

    # Change the registry to set machine permissions.
    Set-MachinePermissions

    # Rename the computer.
    Set-ComputerName

    # Restart the computer after 10 seconds.
    Write-Host "Restarting in 10 seconds..."
    Start-Sleep -Seconds 10
    Restart-Computer -Force
}




# If the script was not dot sourced, set up the computer.
if (-Not ($MyInvocation.InvocationName -eq '.')) {
        Invoke-ComputerSetup
}

4
  • @harrymc Yes. You can see it in the snippet above. It's the 3rd registry value I changed.
    – VidathD
    Jun 22, 2022 at 15:08
  • (Your PowerShell script is too long to read.) I'm starting to think that this has to be done per each user, that there is no global setting for it.
    – harrymc
    Jun 22, 2022 at 20:38
  • @harrymc the only directly relevant part is the snippet at top. I can't find a per-user setting. I'm fine doing that if it's possible.
    – VidathD
    Jun 23, 2022 at 5:04
  • also it's my 1st ever powershell script and like 3rd or 4th any script. Apologies if it's bad or non-standard. Constructive criticism is welcome ☺
    – VidathD
    Jun 23, 2022 at 5:14

1 Answer 1

-1
+50

The values you have modified belong to the default lock screen, meaning that they will be inherited by new user accounts.

For existing user accounts, you will need to modify the values in the regustry.

From my searches, I believe that, for the current user, the following .reg file will set the lock-screen image:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager]

"RotatingLockScreenEnabled"=dword:00000000
"RotatingLockScreenOverlayEnabled"=dword:00000000

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lock Screen\Creative]

"LockImageFlags"=dword:00000000
"CreativeId"=""
"PortraitAssetPath"="PATH-TO-IMAGE-JPG"
"LandscapeAssetPath"="PATH-TO-IMAGE-JPG"
"PlacementId"=""
"ImpressionToken"=""
"HotspotImageFolderPath"="PATH-TO-IMAGE-JPG"
"CreativeJson"=""

The registry entries of all users can be found under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList. They user can be identified by the value of the ProfileImagePath entry. Once you have found the name of the user profile, the information pointed-to by HKEY_CURRENT_USER is found under HKEY_USERS registry hive.


To use PowerShell, see the article How to modify the registry for all users with PowerShell.

I reproduce below the script, for explanations see the article itself.

# Regex pattern for SIDs
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
 
# Get Username, SID, and location of ntuser.dat for all users
$ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | 
    Select  @{name="SID";expression={$_.PSChildName}}, 
            @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, 
            @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
 
# Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
$LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}
 
# Get all users that are not currently logged
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username
 
# Loop through each profile on the machine
Foreach ($item in $ProfileList) {
    # Load User ntuser.dat if it's not already loaded
    IF ($item.SID -in $UnloadedHives.SID) {
        reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
    }
 
    #####################################################################
    # This is where you can read/modify a users portion of the registry 
 
    # This example lists the Uninstall keys for each user registry hive
    "{0}" -f $($item.Username) | Write-Output
    Get-ItemProperty registry::HKEY_USERS\$($Item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | 
        Foreach {"{0} {1}" -f "   Program:", $($_.DisplayName) | Write-Output}
    Get-ItemProperty registry::HKEY_USERS\$($Item.SID)\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
        Foreach {"{0} {1}" -f "   Program:", $($_.DisplayName) | Write-Output}
    
    #####################################################################
 
    # Unload ntuser.dat        
    IF ($item.SID -in $UnloadedHives.SID) {
        ### Garbage collection and closing of ntuser.dat ###
        [gc]::Collect()
        reg unload HKU\$($Item.SID) | Out-Null
    }
}
1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – DavidPostill
    Jun 27, 2022 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.