The new local user and group cmdlets in PowerShell 5.1

With the recent release of PowerShell 5.1—part of Windows Management Framework (WMF) 5.1—Microsoft introduced new cmdlets for working with local user and group accounts: Get-LocalUser, New-LocalUser, Remove-LocalUser, New-LocalGroup, Add-LocalGroupMember, and Get-LocalAdministrators. In this article, I will explore how to use these cmdlets by showing a few simple examples as well as how to perform some advanced tasks.
Profile gravatar of Dan Franciscus

Dan Franciscus

Dan Franciscus is a systems engineer and VMware Certified Professional (VCP) specializing in VMware, PowerShell, and other Microsoft-based technologies. You can reach Dan at his blog or his Twitter at @dan_franciscus.
Profile gravatar of Dan Franciscus

Latest posts by Dan Franciscus (see all)

Prior to this release, having to perform tasks with local users and groups from the Windows command line could be cumbersome. It was necessary to revert to commands such as net user, VB scripting, or using the Active Directory Service Interfaces (ADSI) WinNT provider such as Sitaram showed here on 4sysops.

In my PowerShell console, I can view these commands by typing Get-Command -Module Microsoft.PowerShell.LocalAccounts.

Output of Get Command Module

Output of Get Command Module

Working with local users ^

To illustrate using these cmdlets to work with local users, I will do the following:

  • Show the current local users on my computer
  • Create a new local user named "Dan"
  • Change the password for the "Dan" account
  • Remove the account from my system

First, I run Get-LocalUser, which shows the current users on my machine: the Administrator, the DefaultAccount, and the Guest. By default, the output shows the user name, the description, and whether the account is enabled or not.

I can see all the properties of local users, such as Description, PasswordExpires, and LastLogon, by using Get-LocalUser -Name 'Administrator' | Select-Object *. One scenario where this output would be helpful is if you wanted to see the last time a password was set, which is located in the PasswordLastSet property.

Next, I will create a local account with the username "Dan" and set an initial password using the $Password variable I set with Read-Host. I include the FullName and Description parameters. Note the account is automatically enabled upon creation, similar to what would occur if you created the account in the GUI.

Changing the password for my local account is just a matter of running Set-LocalUser and using the -Password parameter.

To remove the "Dan" account, I run the Remove-LocalUser command while specifying the username of the account in the –Name parameter.

Working with local groups ^

Working with local groups using this module is just as simple as working with local users. With these cmdlets you can create, change, list, rename, and remove local groups. In addition, you can add and remove group members.

In this next example I will show you how to:

  • Create a new local group named "Testgroup"
  • Add members to "Testgroup"
  • Remove group members from "Testgroup"
  • Rename "Testgroup" to "MyGroup"

I create a local group named "Testgroup" by using New-LocalGroup.

Then I add a few members to this group. I will add the local user "Dan" as well as the local groups "Users" and "Remote Desktop Users."

With the Get-LocalGroupMember command, I can see that these users are now members of "Testgroup."

Output of Get LocalGroupMember

Output of Get LocalGroupMember

At this point I have decided I want to remove the user "Dan" from "Testgroup" while keeping the other groups as members. Using Remove-LocalGroupMember and using "Dan" as the value for -Member allows me to do this.

Output shows the Dan user is removed

Output shows the "Dan" user is removed

To rename "Testgroup" to "MyGroup," I use Rename-LocalGroup specifying the -Name and ‑NewName parameters. I can see the name of the group has changed and members are still the same by using Get-LocalGroupMember.

Find domain users that have local administrator rights ^

A best practice for Windows security is ensuring end users do not have local administrator access on their workstations. With a PowerShell function that uses the Get-LocalGroupMember cmdlet, I can quickly find any domain user that is part of the local administrator group for multiple computers.  With the -FilterGroups parameter, I can also filter out any domain users/groups that should have access, such as "Domain Admins."

To validate whether computers in the -ComputerName parameter are online, I included a workflow named Test-Ping. Keep in mind that the clients used in this function require having WMF 5.1 installed.

In this example, I have an Active Directory domain named NTDOMAIN. I run the Get-LocalAdministrators function against all computers contained in the "Windows 10" organizational unit (OU) by using Get-ADComputer and specifying the OU in the -SearchBase parameter. The output of Get-ADComputer is an array of computers, which I then pass to the ‑ComputerName parameter. I use the -FilterGroups parameter to filter out "Domain Admins" and "HelpDeskAdmins" since these groups are supposed to have local administrator access.

The output of Get-LocalAdministrators shows that it found my "NTDOMAIN\DansAccount" domain account in the local administrator group on the computer "WIN10."

Take part in our competition and win $100!

3+

Users who have LIKED this post:

  • avatar

Related Posts

5 Comments
  1. avatar
    Michael 1 week ago

    Very nice!

    Just FYI, at least on larger customers, and at least on hardened servers, it is common to remove "Domain Admins" from the local Administrators group.

    0
  2. Profile gravatar of Matthew Swint
    Matthew Swint 2 days ago

    What was your reasoning for using a workflow to ping the list of computers in $computers?

    0
  3. Profile gravatar of Matthew Swint
    Matthew Swint 2 days ago

    You could have more easily used the following instead of your ping workflow.

    No need for a workflow to ping a list of computers here.

    (I wish comments were editable on this site.)

    0
  4. Profile gravatar of Matthew Swint
    Matthew Swint 2 days ago

    In fact, I don't think you need that BEGIN {} block at all. Then again, this just shows that there's more than one way to skin a cat. Take a look at my revision of your code below.

    0
  5. Profile gravatar of Dan Franciscus Author
    Dan Franciscus 2 days ago

    https://blogs.technet.microsoft.com/heyscriptingguy/2012/11/20/use-powershell-workflow-to-ping-computers-in-parallel/

    This is my reasoning. I prefer a workflow for scalability.

    1+

    Users who have LIKED this comment:

    • avatar

Leave a reply

Your email address will not be published. Required fields are marked *

*

CONTACT US

Please ask IT administration questions in the forum. Any other messages are welcome.

Sending
© 4sysops 2006 - 2017
Do NOT follow this link or you will be banned from the site!

Log in with your credentials

or    

Forgot your details?

Create Account