This post is long over due. I’ve been playing with Windows Server 2012 without the GUI (aka Core) for a while and one thing that irks me is that without the Graphical Management Tools, you’re really stuck using old school “net user” commands. Sure, you can use another GUI 2012 server’s Server Manager to connect and manage your core server, but what if you only have one core server you’re testing? Or, what if you simply want to do things the hard PowerShell way?
I had some ideas, since 2012 Core has the SConfig thing, I decided to do something similar and create a user-management script specifically for this scenario.
So what does it do? Some pretty basic tasks: create & delete users, create & delete groups, as well as edit users. Editing users includes changing the password, enable & disable, and adding & removing group membership. All done from a nice little PowerShell window!
Here’s a screenshot:
It doesn’t do any checking, so if you try to create a user with an existing name, it’ll error out. I could add that in the future, but it’s very simple right now. Here’s the actual script, but I’ll also attach it to the bottom of the post:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
#written by Luke Huckaba #twitter @thephuck #http://thephuck.com param([string]$Computer, [switch]$help) #if help switch is on, lets give some info if($help){ Write-Host -ForegroundColor Green `t "This script helps manage local user accounts, either on the local machine, or by specifying -computer `"compname`" of a remote computer" break } #if computer isn't supplied take the local machine name if(!$Computer){$Computer = $env:COMPUTERNAME} #some script-wide variables Set-Variable -Name userAcct -scope script Set-Variable -Name group -Scope script Set-Variable -Name pw1 -scope script $ADSI = [ADSI]"WinNT://$computer" #main menu function main-list{ cls Write-Host -fore Green `n "Welcome to the PowerShell User & Group Management Script!" `n "Below are a list of available functions:" Write-Host -fore Green `t "-- User Management --" Write-Host -fore Green `t "1 - New User" Write-Host -fore Green `t "2 - Edit User" Write-Host -fore Green `t "3 - Delete User" Write-Host -fore Green `t "-- Group Management --" Write-Host -fore Green `t "4 - Create New Group" Write-Host -fore Green `t "5 - Delete Group" Write-Host -fore Green `t "0 - Exit" [int]$action = Read-Host "Enter the menu number from above" if ($action -eq 0){cls; break} if ($action -eq 1){create-user} if ($action -eq 2){edit-user} if ($action -eq 3){delete-user} if ($action -eq 4){create-group} if ($action -eq 5){delete-group} } function delete-group{ get-group Write-Host -fore Red "You are about to delete $script:group" Confirm("Press 'Y' to continue, or any other key to exit...(Alt+Tab will exit, fyi)") $ADSI.delete("Group",($script:group).tostring()) Write-Host -fore Green `n "$script:group deleted" `n main-list } function create-group{ $script:group = Read-Host "Enter group name" $desc = read-host "Enter description" $groupObj = $ADSI.create("Group", $script:group) $groupObj.SetInfo() $groupObj.description = "$desc" $groupObj.SetInfo() Write-Host -fore Green `n "$script:group created" `n main-list } function create-user{ $script:userAcct = Read-Host "Enter username" $desc = read-host "Enter description" getPassword $userObj = $ADSI.create("User", $script:userAcct) $userObj.setPassword($script:pw1) $userObj.SetInfo() $userObj.description = "$desc" $userObj.SetInfo() Write-Host -fore Green `n "$script:userAcct created" `n main-list } function edit-user{ get-user Write-Host -fore Green `t "What would you like to do?" Write-Host -Fore Green `t "1 - Change Password" Write-Host -Fore Green `t "2 - Add to User Group" Write-Host -Fore Green `t "3 - Remove from User Group" Write-Host -Fore Green `t "4 - Disable User" Write-Host -Fore Green `t "5 - Enable User" Write-Host -Fore Green `t "M - Main Menu" $EditUser = Read-Host "Enter task number" #change the password if ($EditUser -ieq "m"){main-list} if ($EditUser -eq "1"){ getPassword $userObj = $ADSI.create("User", $script:userAcct) $userObj.setPassword($script:pw1) write-host -fore Green `n "Password set" `n } #add user to group if ($EditUser -eq "2"){ get-group $groupObj = [ADSI]"WinNT://$computer/$script:group" $userObj = [ADSI]"WinNT://$computer/$script:userAcct" $groupObj.Add($userObj.Path) Write-Host -Fore Green `n "$script:userAcct added to $script:group" `n } #remove user from group if ($EditUser -eq "3"){ Write-Host -fore Green `t "$script:userAcct is a member of the following groups" ([ADSI]"WinNT://$computer/$script:userAcct").psbase.invoke('Groups') | foreach {Write-Host -fore green `t $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)} Write-Host -fore green `t "M - Main Menu" $groupname = Read-Host "Enter the group to remove the user from" if($groupname -ieq "M"){main-list} $groupObj = [ADSI]"WinNT://$computer/$groupname" $userObj = [ADSI]"WinNT://$computer/$script:userAcct" $groupObj.Remove($userObj.Path) Write-Host -Fore Green `n "$script:userAcct removed from $groupname" `n } #disable user if ($EditUser -eq "4"){ Write-Host -fore Red "You are about to disable $script:userAcct" Confirm("Press 'Y' to continue, or any other key to exit...(Alt+Tab will exit, fyi)") $userObj = [ADSI]"WinNT://$computer/$script:userAcct" $userObj.description = "Account Disabled" $userObj.userflags = 2 $userObj.setinfo() Write-Host -fore Green `n "$script:userAcct disabled" `n } #enable user if ($EditUser -eq "5"){ Write-Host -fore Red "You are about to enable $script:userAcct" Confirm("Press 'Y' to continue, or any other key to exit...(Alt+Tab will exit, fyi)") $userObj = [ADSI]"WinNT://$computer/$script:userAcct" $desc = read-host "Enter description" $userObj.description = "$desc" $userObj.userflags = 512 $userObj.setinfo() Write-Host -fore Green `n "$script:userAcct enabled" `n } main-list } function delete-user{ get-user Write-Host -fore Red "You are about to delete $script:userAcct" Confirm("Press 'Y' to continue, or any other key to exit...(Alt+Tab will exit, fyi)") $ADSI.delete("User",($script:userAcct).tostring()) Write-Host -fore Green `n "$script:userAcct deleted" `n main-list } #function to populate our user acct script variable function get-user{ $users = $ADSI.Children | ? {$_.SchemaClassName -eq 'user'} $i = 0 foreach ($user in $users){ Write-Host -fore Green `t $user.Name $i++ } Write-Host -fore Green `t "M - Main Menu" $script:userAcct = (read-Host "Enter the user you wish to edit").ToLower() if ($script:userAcct -ieq "M"){main-list} } #function to populate our group script variable function get-group{ $users = $ADSI.Children | ? {$_.SchemaClassName -eq 'group'} $i = 0 foreach ($user in $users){ Write-Host -fore Green `t $user.Name $i++ } Write-Host -fore Green `t "M - Main Menu" $script:group = (read-Host "Enter the group you wish to edit").ToLower() if ($script:group -ieq "M"){main-list} } #function to populate our password script variable, also compares to make sure it's not fat-fingered function getPassword() { $script:pw1 = read-host -assecurestring `n "Enter password for new user" $pw2 = read-host -assecurestring `n "Re-Enter password" $String1 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($script:pw1) $String2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw2) $script:pw1 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($String1) $pw2 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($String2) $match = $script:pw1.CompareTo($pw2) if ($match -ne 0) { write-host -foregroundcolor red `n "Passwords do not match!" `n getPassword } } #function to prompt for confirmation function Confirm($strMessage){ write-host -foregroundcolor yellow `n $strMessage $answer = $host.ui.rawui.readkey("NoEcho,IncludeKeyUp") if ($answer.Character -ine "y"){ write "" main-list } write "" } #lets get this party started! main-list |
Here’s the link to the .ps1 file itself: PS-User-Mgmt.ps1
Happy scripting everyone!
Looks great Luke! Just checked the site from my Powershell class and that was your newest post. What a coincidence!
Awesome! What class, and how’s it going?
When you point the script to a DC and try to do any function with a user it list out all of the users in AD?? Is there something I am missing here?
No, it basically pulls all user accounts at the top level. I wrote it to manage a single/standalone Core instance of Windows Server that isn’t joined to a domain with centralized management. The script doesn’t have a concept of OUs, or any structure, really.