Summary: Microsoft Scripting Guy Ed Wilson shows how to add local users to local groups using Windows PowerShell.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I have enjoyed your posts this week. It is amazing how often I need to enable the Local Administrator account, or create a new local user or group. One thing you have left out, however, is how I add a local user to a local group. In addition, I am using Windows PowerShell 2.0, therefore you do not need to worry about backward compatibility.

-- EJ

 

Hey, Scripting Guy! AnswerHello EJ, Microsoft Scripting Guy Ed Wilson here. I am glad you have been enjoying my local user blog posts this week. You are right; the ability to create a local user and to create a local group is only half of the equation. To complete the local management story one must be able to add a user to a group. Because you do not need backward compatibility with Windows PowerShell 1.0, I am going to use a script that I wrote for the Windows 7 Resource Kit. The Windows PowerShell 2.0 features that it uses are the help tags. If one needed to, they could modify the script rather easily to work on Windows PowerShell 1.0 by changing out the help tags with the here-string syntax I have used earlier this week.

The Microsoft Press Windows 7 Resource Kit is the authoritative reference book for IT Pros and others who wish to learn Windows 7. I wrote the chapter on Windows PowerShell for the book, as well as writing nearly 200 scripts for the book. It was a fun project.

The complete Add-LocalUserToLocalGroup.ps1 script is seen here.

Add-LocalUserToLocalGroup.ps1

<#

   .Synopsis

    Adds a local user to a local group on either a local or remote machine.

   .Description

    This script uses [adsi] type accelerator to use ADSI to create a local group.

    It will throw an error if $group is not present. It uses the WinNT provider to

    connect to local SAM database. This is case sensitive. This script must run with

    ADMIN rights to create local groups.

   .Example

    Add-LocalUserToLocalGroup.ps1 -computer MunichServer -user myUser -group mygroup

    Adds a local user called myUser on a computer named MunichServer to a local group called mygroup

   .Example

    Add-LocalUserToLocalGroup.ps1 -user myUser -group mygroup

    Adds a local user called myUser on local computer to a group called mygroup

   .Inputs

    [string]

   .OutPuts

    [string]

   .Notes

    NAME:  Windows 7 Resource Kit

    AUTHOR: Ed Wilson

    LASTEDIT: 5/20/2009

    KEYWORDS: ADSI

   .Link

     Http://www.ScriptingGuys.com

#Requires -Version 2.0

#>

param(

      $computer=$env:computerName,

      [Parameter(mandatory=$true)]

      $user,

      [Parameter(mandatory=$true)]

      $group

) #end param

# *** Functions

function New-Underline

{

<#

.Synopsis

 Creates an underline the length of the input string

.Example

 New-Underline -strIN "Hello world"

.Example

 New-Underline -strIn "Morgen welt" -char "-" -sColor "blue" -uColor "yellow"

.Example

 "this is a string" | New-Underline

.Notes

 NAME:

 AUTHOR: Ed Wilson

 LASTEDIT: 5/20/2009

 KEYWORDS:

.Link

 Http://www.ScriptingGuys.com

#>

[CmdletBinding()]

param(

      [Parameter(Mandatory = $true,Position = 0,valueFromPipeline=$true)]

      [string]

      $strIN,

      [string]

      $char = "=",

      [string]

      $sColor = "Green",

      [string]

      $uColor = "darkGreen",

      [switch]

      $pipe

 ) #end param

 $strLine= $char * $strIn.length

 if(-not $pipe)

  {

   Write-Host -ForegroundColor $sColor $strIN

   Write-Host -ForegroundColor $uColor $strLine

  }

  Else

  {

  $strIn

  $strLine

  }

} #end New-Underline function

 

function Test-IsAdministrator

{

    <#

    .Synopsis

        Tests if the user is an administrator

    .Description

        Returns true if a user is an administrator, false if the user is not an administrator        

    .Example

        Test-IsAdministrator

    #>  

    param()

    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()

    (New-Object Security.Principal.WindowsPrincipal $currentUser).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

} #end function Test-IsAdministrator

 

# *** Entry point to script ***

If(-not (Test-IsAdministrator)) { New-Underline "Admin rights are required for this script" ; exit }

 

if(!$user -or !$group)

      {

       $(Throw 'A value for $user and $group is required.')

        }

     

$OBjOU = [ADSI]"WinNT://$computer/$group,group"

$objOU.add("WinNT://$computer/$user")

 

The Add-LocalUserToLocalGroup.ps1 script is rather long, but what it does is not very complicated. In fact, most of the code is taken up with the comment-based help. The script begins with a comment block that provides command line help for the script. The comment block is listed here.

<#

   .Synopsis

    Adds a local user to a local group on either a local or remote machine.

   .Description

    This script uses [adsi] type accelerator to use ADSI to create a local group.

    It will throw an error if $group is not present. It uses the WinNT provider to

    connect to local SAM database. This is case sensitive. This script must run with

    ADMIN rights to create local groups.

   .Example

    Add-LocalUserToLocalGroup.ps1 -computer MunichServer -user myUser -group mygroup

    Adds a local user called myUser on a computer named MunichServer to a local group called mygroup

   .Example

    Add-LocalUserToLocalGroup.ps1 -user myUser -group mygroup

    Adds a local user called myUser on local computer to a group called mygroup

   .Inputs

    [string]

   .OutPuts

    [string]

   .Notes

    NAME:  Windows 7 Resource Kit

    AUTHOR: Ed Wilson

    LASTEDIT: 5/20/2009

    KEYWORDS: ADSI

   .Link

     Http://www.ScriptingGuys.com

#Requires -Version 2.0

#>

 

For information about using help tags, see this Hey, Scripting Guy! Blog post.  When Get-Help is used with the path to the script, the output shown in the following figure appears.

The New-Underline function is used to underline output. It accepts pipelined input, and I often use it when displaying output. It is talked about in this Hey, Scripting Guy! Blog post. The complete text of this function is seen here. The function contains its own help, and can easily be incorporated into a profile.

function New-Underline

{

<#

.Synopsis

 Creates an underline the length of the input string

.Example

 New-Underline -strIN "Hello world"

.Example

 New-Underline -strIn "Morgen welt" -char "-" -sColor "blue" -uColor "yellow"

.Example

 "this is a string" | New-Underline

.Notes

 NAME:

 AUTHOR: Ed Wilson

 LASTEDIT: 5/20/2009

 KEYWORDS:

.Link

 Http://www.ScriptingGuys.com

#>

[CmdletBinding()]

param(

      [Parameter(Mandatory = $true,Position = 0,valueFromPipeline=$true)]

      [string]

      $strIN,

      [string]

      $char = "=",

      [string]

      $sColor = "Green",

      [string]

      $uColor = "darkGreen",

      [switch]

      $pipe

 ) #end param

 $strLine= $char * $strIn.length

 if(-not $pipe)

  {

   Write-Host -ForegroundColor $sColor $strIN

   Write-Host -ForegroundColor $uColor $strLine

  }

  Else

  {

  $strIn

  $strLine

  }

} #end New-Underline function

 

Because adding a user to a group is a privileged operation, the script requires Administrator rights. I wrote the Test-IsAdministrator function to perform that check. This is another function I often use in my scripts, and it also makes a great candidate for a profile. Refer to this Hey Scripting Guy! Blog post for information about using the Test-IsAdministrator function.

function Test-IsAdministrator

{

    <#

    .Synopsis

        Tests if the user is an administrator

    .Description

        Returns true if a user is an administrator, false if the user is not an administrator       

    .Example

        Test-IsAdministrator

    #>  

    param()

    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()

    (New-Object Security.Principal.WindowsPrincipal $currentUser).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

} #end function Test-IsAdministrator

 

The actual code that adds a user to a group is easy. I use the WinNT provider and connect to a specific group on a computer. I then call the add method and pass the user from the computer. The group and the user name are supplied via the command line when the script is called.

Note: WinNT, as used in the code below, is case sensitive. This is something that is unusual for Windows PowerShell because Windows PowerShell is normally case insensitive. The case sensitivity itself, however, for the WinNT provider name comes from ADSI and is not a result of Windows PowerShell itself.

This code is seen here:

$objOU = [ADSI]"WinNT://$computer/$group,group"

$objOU.add("WinNT://$computer/$user")

 

The script can be called in a couple of ways. Here are two examples:

Add-LocalUserToLocalGroup.ps1 -computer MunichServer -user myUser -group mygroup

Add-LocalUserToLocalGroup.ps1 -user myUser -group mygroup

 

In addition, you could supply information via a text file and loop through the information in the file if you need to add multiple users and groups.

EJ, that is all there is to using Windows PowerShell to add a local user to a local group. This also concludes local user week. Join me tomorrow as I open my virtual mail bag and answer a raft of miscellaneous questions.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy