Powershell Reflections
Discovering useful methods in Powershell through Reflection.
Skip to content
  • Home
  • Scripting Games 2013
  • Beginner
  • Xbox 360
  • About
← Querying Remote Servers for Information
Get User Roles in Sharepoint 2007 →

Adding Domain Users to Local Groups

Posted on 05/03/2011 by Jonathan Tyler

I am sure this topic has been covered many times before on other forums and blog posts, but here is my contribution to this activity.  With the push for advanced functions during the 2011 Scripting Games, I think I would be remiss to not use that functionality on this script.

To start an advanced function, I need to declare the CmdletBinding() attribute at the beginning.  This allows for parameter attributes that can make this script work just like a normal compiled cmdlet.  I also need to define what types of parameters I can accept as well.

[CmdletBinding(DefaultParameterSetName="Bulk")]
    Param(
        [parameter(Mandatory=$true,
                  ParameterSetName="Single")]
        [string]$ComputerName=$env:ComputerName,
        [parameter(Mandatory=$true)]
        [string]$localGroup,
        [parameter(ParameterSetName="Single")]
        [string]$domainUser,
        [parameter(ParameterSetName="Single")]
        [string]$domainGroup,
        [parameter(Mandatory=$true,
                  ParameterSetName="Bulk")]
        [string]$csvFile
)

I have used two types of parameter decorations to specify the types of information required to process this script.  I have two different parameter set names: “Single” and “Bulk.”  I have also specified that some of the parameters are required.  In a minute, I will show you how to process which parameter set was given.  The CmdletBinding() attribute declares which parameter set I expect to get.

Now to determine what we have to work with…Is it a file name or a username and group name?  First, I will use the Switch statement to determine which parameter set was used.  However, with Powershell, if the parameter give is ambiguous (all of ours are string parameters, so how does it know?), it will go with what we defined above as the DefaultParameterSetName or the “Bulk” option. 

switch ($PSCmdlet.ParameterSetName)
{
    "Single" {<Single user code block>}
    "Bulk"   {<Bulk user code block>}
}

I intentionally left out all the code for each type of parameter set to make the snippets more readable here.  The full code listing at the end will bring that all together.  Since the basic idea of this script is to add a domain object (user or group) to a local group, I will set up a function inside this script to handle only that operation.  By design, this allows the script to accept input from different types of sources and still use the same basic code to do the real operation I am trying to accomplish.

Function Add-DomainObjectToLocal
    {
        Param($computer,$localgroup,$domain,$object)
  
        try
        {
            Write-Host "Adding $domain\$object to $localgroup on $computer."
            ([ADSI]"WinNT://$computer/$localgroup,group").Add("WinNT://$domain/$object")
        }
        catch
        {  
            Write-Host "An error occurred: $_."
        }
    }

This function will be inside the script and can be used no matter what input is given, as you will see in a moment.  I have also provided a method to give feedback to the user in case there is a problem with any of the items trying to be processed.  If, for instance, the domain group is already a member of the local group, an exception will be generated.  The CATCH block here will intercept the error and provide a message to the user saying so.

For now, let’s look at processing the “Single” parameter set.  This code block would go in the first switch code block (Where <Single User Code Block> is).  All we do here is to call the function I just created with the appropriate parameters.

if ($domainGroup){$domainObject = $domainGroup}else{$domainObject=$domainUser}
Add-DomainObjectToLocal -computer $Computername -localGroup $localGroup -domain $env:USERDOMAIN -object $domainObject

I took a little bit of a shortcut here.  I am making an assumption on my script that a given group will take precedence over a given user assuming that both were provided simulatneously.  In real life, I would probably want to check to make sure that at least one of these parameters was populated before trying to execute the function.  Instead, I am assuming that if I don’t have a group, that the user supplied a domain user object.

Now we can focus attention on the file input.  This assumes that the CSV file to read has two columns: Server and Group.  A sample CSV file might look like this:

Server,Group
MyServer1,ApplicationGroup1
MyServer1,ApplicationGroup2

Once we get the file loaded, we can recurs through each line to get each group added to the proper server. 

$groupInformation = Import-CSV -Path $csvFile
Foreach ($item in $groupInformation)
{
    Add-DomainObjectToLocal -computer $item.Server -localGroup $localGroup -domain $env:USERDOMAIN -object $item.Group
}

And that pretty much finishes the script.  There are some additional things that could be done here.  For instance, we could set the $ComputerName, $domainUser, or $domainGroup to accept pipeline input.  In the full script source below, however, I have added the comment-based help that allows users to use the built-in help system to see how to use the script.

Please leave me a comment about your thoughts on this script.

<#
.SYNOPSIS
   Adds domain users or groups to the specified local computer group.
  
.DESCRIPTION
   Using either a CSV file or specific objects, the user can add a domain user or
   group to a local computer group. 
  
   If a domain user and domain group are both specified, the domain group will get
   priority and the domain user will be ignored.
  
   This script operates off of the executing user's domain.
 
.PARAMETER ComputerName
 Specifies the computer to add the domain user or group to.
 
.PARAMETER localGroup

 Specifies the local security group to add the domain user or group to.
 
.PARAMETER domainUser

 Specifies a domain user to add to a local security group.
 
.PARAMETER domainGroup

 Specifies a domain group to add to a local security group.  If both a user
 and group are specified, the group will take precedence and the user will
 be ignored.  
  
.EXAMPLE
 C:\PS> .\Add-DomainObjectLocal.ps1 -csvFile groups.csv -localGroup Administrators
  
 Description
 -----------
 This command reads the Server and Group information from the groups.csv file and
 adds them to the Administrators group on each named server in the file.
 
.EXAMPLE
 C:\PS> .\Add-DomainObjectLocal.ps1 -localGroup "Backup Operators" -domainGroup "Domain Backup Operators"
 
 Description
 -----------
 This command adds the domain group "Domain Backup Operators" to the local
 "Backup Operators" security group on the local machine.
  
#>

[CmdletBinding(DefaultParameterSetName="Bulk")]
    Param(
        [parameter(ParameterSetName="Single")]
        [string]$ComputerName=$env:ComputerName,
        [parameter(Mandatory=$true)]
        [string]$localGroup,
        [parameter(ParameterSetName="Single")]
        [string]$domainUser,
        [parameter(ParameterSetName="Single")]
        [string]$domainGroup,
        [parameter(Mandatory=$true,
            ParameterSetName="Bulk")]
        [string]$csvFile
    )

    Function Add-DomainObjectToLocal
    {
        Param($computer,$localgroup,$domain,$object)
  
        try
        {
            Write-Host "Adding $domain\$object to $localgroup on $computer."
            ([ADSI]"WinNT://$computer/$localgroup,group").Add("WinNT://$domain/$object")
        }
        catch
        {  
            Write-Host "An error occurred: $_."
        }
    }
 
switch ($PSCmdlet.ParameterSetName)
{   
    "Single" {
                if ($domainGroup)
                {
                    $domainObject = $domainGroup
                }
                else
                {
                    $domainObject=$domainUser
                }
                Add-DomainObjectToLocal -computer $Computername -localGroup $localGroup -domain $env:USERDOMAIN -object $domainObject
            }
    "Bulk"   {
                $groupInformation = Import-CSV -Path $csvFile
                Foreach ($item in $groupInformation)
                {
                    Add-DomainObjectToLocal -computer $item.Server -localGroup $localGroup -domain $env:USERDOMAIN -object $item.Group
                }
            }
}
<pre>
About these ads

Share this:

  • More

Like this:

Like Loading...
This entry was posted in Account Objects, Active Directory, ADSI, Advanced Function and tagged $env, CmdletBinding, functions, import-csv, local groups, parameters, parametersetname, try/catch, WinNT. Bookmark the permalink.
← Querying Remote Servers for Information
Get User Roles in Sharepoint 2007 →
  • Microsoft TechEd 2013

    I'm attending MSTechED North America 2013
  • 2013 Powershell Scripting Games

    2013 Powershell Scripting Games #Psh2013

  • Follow @jonhtyler
  • Get-ToThePrompt -at PowerGUI.org

  • Top Posts & Pages

    • Using Powershsell to Access SQL Data
    • My Adventures with Powershell and Charting Tools
    • Control Your ScreenSaver With Powershell
    • Get User Roles in Sharepoint 2007
    • Adding Domain Users to Local Groups
    • Dude, Where Are My Printers?
    • What...or How do you get something out of Powershell?
    • Clearing Your Akamai Content Delivery Network Cache with Powershell
    • Gathering the Number of Event Log Entries Over a Given Time-frame
    • Querying Remote Servers for Information
  • Categories

    • Account Objects (2)
    • Active Directory (3)
    • ADSI (2)
    • Advanced Function (6)
    • Beginner (1)
    • Cmdlet Help (3)
    • Event Logs (1)
    • Graphing (1)
    • PSObjects (4)
    • Scripting (7)
    • Scripting Games (1)
    • Scripting Games 2013 (3)
    • Sharepoint 2007 (5)
    • SQL (1)
    • SqlClient (1)
    • Uncategorized (2)
    • WMI (3)
    • Xbox 360 (3)
    • XML (5)
  • Tags

    $env 2007 Application programming interface Calculated Property CmdletBinding docicon Event Log Export-CSV functions Get-QADUser Get-WMIObject hashtables import-csv JSON LastLogonTimeStamp local groups looping Microsoft SharePoint Northwind object output parameters parametersetname Programming Scripting Games SELECT sharepoint sort-object Sql.DataSet SqlClient SqlConnection SqlDataAdapter Statistics TimeGenereated try/catch Windows PowerShell WinNT WMI Write-Host Write-Output Xbox 360 Xbox Live XML XMLDocument XPath
  • Archives

  • RSS Scripting Games Feed

    • Get a List of all Windows TimeZones with Windows Powershell 06/18/2013 Sean Kearney
    • PowerShell Great Debate: Capturing Errors 06/17/2013 Don Jones
    • Charlotte User Group July Meeting 06/13/2013 ScriptingWife
    • Philadelphia Meeting – July 11th, 2013 06/13/2013 Lido
    • PowerShell Great Debate: Error Trapping 06/11/2013 Don Jones
  • Blogroll

    • ShellHub – Don Jones' Powershell Resources
    • Hey, Scripting Guy!
    • Huddled Masses
    • The Lonely Administrator – Jeff Hicks
    • Richard Siddaway's Blog
    • Use Powershell – Steven Murawski
  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 330 other followers

  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • Blog at WordPress.com.
  • Blog Stats

    • 26,064 hits
  • RSS Feed RSS - Posts

    RSS Feed RSS - Comments

Powershell Reflections
Theme: Twenty Ten Blog at WordPress.com.
Follow

Get every new post delivered to your Inbox.

Join 330 other followers

Powered by WordPress.com
loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.
%d bloggers like this: