microsoft_windows:adduser_powershell
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
microsoft_windows:adduser_powershell [2025/05/15 18:39] – created rodolico | microsoft_windows:adduser_powershell [2025/05/25 01:24] (current) – rodolico | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Add/Update User with PowerShell ====== | ====== Add/Update User with PowerShell ====== | ||
+ | ===== Discussion ===== | ||
We needed a way to automatically update a local user on a bunch of systems which were not on an Active Directory configuration. We had remote access, and the ability to run PowerShell scripts as an administrator. | We needed a way to automatically update a local user on a bunch of systems which were not on an Active Directory configuration. We had remote access, and the ability to run PowerShell scripts as an administrator. | ||
It should not be interactive at all. | It should not be interactive at all. | ||
- | The first step is to generate a password | + | The following |
- | <code powershell | + | My initial, simplistic code did not take into account that when you create a secure passsword with no encryption key, it uses a key attached to the machine and user (maybe just the user). The result is that it will work just fine when run by the user on the same machine that generated it, but fails on other machines. |
- | $password = ConvertTo-SecureString -String | + | |
- | $plain = convertFrom-securestring | + | Note: I put a lot of comments in the scripts to explain what is going on. The actual code is very small. |
- | $plain | + | |
+ | ===== Generate password hash ===== | ||
+ | |||
+ | The first step is to generate a password, and encrypt it with a randomly generated key. This will save the results to two files, aes.key and encrypted_password.txt. | ||
+ | |||
+ | Run this script one time and put the contents of the key and the encrypted passwords files into updateUser.ps1. Each time this is run, a new key is generated. | ||
+ | |||
+ | <code powershell | ||
+ | # script to create a secure password and save it encrypted | ||
+ | # This will accept a password input from the user, generate a random key, | ||
+ | # and save both the key and the encrypted password to files. | ||
+ | # This was createed to be used with the updateUser.ps1 script | ||
+ | # with the help of Copilot. | ||
+ | |||
+ | |||
+ | # Ensure the script is run with administrative privileges | ||
+ | # Requires -Version 5.1 | ||
+ | # Requires -RunAsAdministrator | ||
+ | |||
+ | # Prompt for password | ||
+ | $password = Read-Host "Enter password" | ||
+ | |||
+ | # Generate a random key and save it | ||
+ | # Note: a new random key is generated each time this script runs. | ||
+ | # we save teh contents of the key to a file named aes.key | ||
+ | # This key should be kept secure and not shared publicly. | ||
+ | $key = New-Object Byte[] 32 | ||
+ | [Security.Cryptography.RNGCryptoServiceProvider]:: | ||
+ | Set-Content -Path " | ||
+ | |||
+ | # Export the secure string using the key | ||
+ | # The password | ||
+ | # Note: The encrypted password will be saved in a file named encrypted_password.txt | ||
+ | $password | ConvertFrom-SecureString -Key $key | Set-Content " | ||
</ | </ | ||
- | The final line will give a very long hex number, which is the hash of the password (" | + | ===== Download |
- | <code powershell adduser.ps> | + | Download the following Powershell file and edit in your favorite text editor. Paste the output of the previouss |
- | # script | + | |
- | # Generate | + | |
- | # | + | |
- | # $password = ConvertTo-SecureString -String "password" | + | |
- | # $plain = convertFrom-securestring -securestring $password | + | |
- | # $plain | + | |
- | # | + | |
- | # paste the output into -String below | + | |
- | # adjust the user and which group to add them to. | + | |
- | # if user already exists, will ignore (with message. | + | |
- | # password is updated no matter what | + | |
- | # if user is already in group, will ignore (with message) | + | |
- | $password = ConvertTo-SecureString -String "Very Long Hex String from above" | + | Adjust the following to your needs |
+ | * $username: Replace with the username to update/ | ||
+ | * $key: Replace the comma separated integers with the 32 integers in the file aes.key | ||
+ | * $securePassword: | ||
+ | * $fullName: This is the diplay name of the user | ||
+ | * $description: | ||
+ | * $localGroup: | ||
- | $user = ' | ||
- | $group = " | ||
- | # Check if user exists | + | <code powershell updateUser.ps1> |
- | if (-not (Get-LocalUser -Name $user -ErrorAction SilentlyContinue)) { | + | # Script to create or update a local user with a secure password |
+ | # This script checks if a local user exists, creates it if not, and sets the password. | ||
+ | # It also ensures the user is part of the Administrators group. | ||
+ | # Requires -Version 5.1 | ||
+ | # Requires -RunAsAdministrator | ||
+ | |||
+ | # this is insecure because both the key and the encrypted password are stored in plaintext within the script. | ||
+ | # and can be reversed to obtain the original password. | ||
+ | # This script is intended to be used with the makepass.ps1 script, which generates a secure password and key | ||
+ | # and saves it encrypted. | ||
+ | |||
+ | # For security, consider this password to be obscured, NOT secured. | ||
+ | |||
+ | # Define variables | ||
+ | # you must define $username, $key, and $securePassword variables before running this script. | ||
+ | |||
+ | |||
+ | # Ensure the username is valid and does not contain special characters | ||
+ | $userName = "Enter Username Here" # Replace with the actual username you want to create or update | ||
+ | |||
+ | # Replace with your actual key, contents of aes.key file | ||
+ | # The keyfile has 32 bytes, newline separated. Replace newlines with commas, | ||
+ | # and paste below. | ||
+ | # Example key: 96, | ||
+ | # Ensure the key is a byte array of 32 bytes | ||
+ | # Note: The key must be exactly 32 bytes for AES-256 encryption | ||
+ | $key = [Byte[]](1, | ||
+ | |||
+ | # Enter the contents of the file encrypted_password.txt here, within quotes. | ||
+ | # This should be the output from ConvertFrom-SecureString using the same key. | ||
+ | # Example: ' | ||
+ | # Note: The encrypted key will end with ' | ||
+ | $securePassword = ' | ||
+ | |||
+ | $fullName = "" | ||
+ | $description = "" | ||
+ | $localGroup = "" | ||
+ | |||
+ | # if $fullName is empty or null | ||
+ | if (-not $fullName) { | ||
+ | $fullName = $userName | ||
+ | } | ||
+ | |||
+ | # if $description is empty or null | ||
+ | if (-not $description) { | ||
+ | $description = "User created by script" | ||
+ | } | ||
+ | |||
+ | # if $localGroup is empty or null | ||
+ | if (-not $localGroup) { | ||
+ | $localGroup = " | ||
+ | } | ||
+ | |||
+ | # Check if user exists, create if not | ||
+ | if (-not (Get-LocalUser -Name $userName | ||
try { | try { | ||
- | New-LocalUser -Name $user | + | New-LocalUser -Name $userName |
- | Write-Host "User '$user' created." | + | |
} catch { | } catch { | ||
- | Write-Warning | + | Write-Error " |
+ | exit 1 | ||
} | } | ||
- | } else { | ||
- | Write-Host "User ' | ||
} | } | ||
- | # Set (or reset) | + | # Set the password |
try { | try { | ||
- | Set-LocalUser -Name $user -Password $password | + | Set-LocalUser -Name $userName |
- | Write-Host " | + | |
} catch { | } catch { | ||
- | Write-Warning | + | Write-Error " |
+ | exit 1 | ||
} | } | ||
- | # Add to local group if not already a member | + | # Ensure user is in correct |
- | try { | + | if (-not (Get-LocalGroupMember -Group $localGroup |
- | | + | try { |
- | Add-LocalGroupMember -Group $group -Member $user | + | Add-LocalGroupMember -Group $localGroup |
- | Write-Host "User ' | + | } catch { |
- | } else { | + | Write-Error "Failed to add user '$userName' |
- | Write-Host "User '$user' | + | exit 1 |
} | } | ||
- | } catch { | ||
- | Write-Warning " | ||
} | } | ||
+ | # Output success message | ||
+ | Write-Host "User ' | ||
</ | </ | ||
+ | |||
+ | ===== Run the code ===== | ||
+ | |||
+ | You can run the code by opening PowerShell as Administrator, | ||
+ | |||
+ | ===== Enhancements ===== | ||
+ | |||
+ | * Do not send the script over any public media like e-mail. You can safely send the $key line, or the $securePassword line, but not both. | ||
+ | * Multiple groups could be set up by changing group to an array and then looping through them. | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | ===== Links ===== | ||
+ | * This was all built on Linux ([[https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * Script was generated with the help of Copilot. While I had a majority of it written beforehand, Copilot became a shortcut to doing the whole AES thing. | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | Also, thanks to DavidN for tightening it up a little for me. |
microsoft_windows/adduser_powershell.1747352374.txt.gz · Last modified: 2025/05/15 18:39 by rodolico