MrMeaner MrMeaner - 3 months ago 15
PowerShell Question

Add computers to security groups - Powershell GUI?

This week I was tasked with question/problem: How can you add computers to security groups within an OU using a functioning Powershell GUI interface consisting of various computer name input methods:-


  • Localhost

  • Manual hostname entry

  • Load computer list from file



As I couldn't find anything similar on the web so I thought I'd post the question here...

Answer

I managed to write the code myself.

Only thing that needs updating to work in another enviroment is the $OU variable (at the top of the code).

Copy code segment and save as .ps1

The code relies on the ActiveDirectory module and if not available locally it will connect to a domain controller and run a remote Powershell session.

NOTE: The code assumes WinRM service on DC's is setup for remote management if the ActiveDirectory module is not installed locally.

Install Software App

Enjoy!

Here is the complete and working code:-

#Generated Form Function
function GenerateForm {
########################################################################
# Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.10.0
# Generated On: 25/03/2013 4:56 PM
# Generated By: MrMeaner
########################################################################

#Custom OU variable
$OU = "OU=TESTScripts,OU=Groups,OU=Company,DC=Company,DC=local"

#Runs load_module function that tests for ActiveDirectory module
load_module


#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$radioButton3 = New-Object System.Windows.Forms.RadioButton
$radioButton2 = New-Object System.Windows.Forms.RadioButton
$radioButton1 = New-Object System.Windows.Forms.RadioButton
$label3 = New-Object System.Windows.Forms.Label
$textHostname = New-Object System.Windows.Forms.Label
$txtHostname = New-Object System.Windows.Forms.TextBox
$Install = New-Object System.Windows.Forms.Button
$label1 = New-Object System.Windows.Forms.Label
$Browse = New-Object System.Windows.Forms.Button
$ListApps = New-Object System.Windows.Forms.ComboBox
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
#Provide Custom Code for events.

$Browse_OnClick= 
{
#When Browse button is clicked
$FileName = Select-FileDialog
    if (!$FileName) {}
    else {
        $Computers = Get-Content $FileName
        $Install.enabled = $true
    }
}

$Install_OnClick= 
{
#Add computer to security group script

    if (!$ListApps.SelectedItem) {
        [System.Windows.Forms.MessageBox]::Show("Please select an SCCM application install group name from the drop down menu","Sorry!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Warning) 
        }

    else {

        $AppGroup = $ListApps.SelectedItem.ToString()

        $Group = Get-ADGroup -Identity $AppGroup 

            foreach ($Hostname in $Computers){

                $member = Get-ADComputer -Identity "$Hostname" -Properties MemberOf | Select-Object MemberOf
                $pc = Get-ADComputer "$Hostname" | Select -expand SamAccountName

                if ($member.Memberof -like "$Group"){
                    [System.Windows.Forms.MessageBox]::Show("$Hostname is already a member of $AppGroup","Whoops!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Question)
                }

                else {
                    Add-ADGroupMember $AppGroup $pc -passthru
                    [System.Windows.Forms.MessageBox]::Show("$Hostname has been added to $AppGroup", "Success!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Information)  

                }
            }  
    }

}

$handler_radioButton1_CheckedChanged= 
{
#Localhost radio button
$txtHostname.enabled = $false
$Browse.enabled = $false
$Computers = $env:computername
$Install.enabled = $true

}

$handler_radioButton2_CheckedChanged= 
{
#Enter Hostname radiobutton
$Install.enabled = $false
$txtHostname.enabled = $true
$Browse.enabled = $false
}

$handler_radioButton3_CheckedChanged= 
{
#Load list of computers radiobutton
$Install.enabled = $false
$Browse.enabled = $true
$txtHostname.enabled = $false

}

$handler_textBox1_TextChanged= 
{
#Hostname textbox
$Computers = $txtHostname.Text.ToString()

    if (!$computers) {
        [System.Windows.Forms.MessageBox]::Show("Please enter hostname","Try Again!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Warning)
    }
    else {   

        $queryCount = @(dsquery computer -name $computers).count

        if ($queryCount -eq 1) {
            $Install.enabled = $true
        }

        elseif ($queryCount -gt 1) {
            [System.Windows.Forms.MessageBox]::Show("Ambiguous name: $computers","Try Again!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Warning)
            $Install.enabled = $false
        }

        else {
            [System.Windows.Forms.MessageBox]::Show("Computer not found in AD: $computers","Try Again!",[windows.forms.messageboxbuttons]::Ok, [windows.forms.messageboxicon]::Warning)
            $Install.enabled = $false
        }

    }
}

$handler_form1_Load= 
{
#Runs when script is loaded
$txtHostname.enabled = $false
$Browse.enabled = $false
$Install.enabled = $false
$AppGroupList = Get-ADGroup -Filter {GroupCategory -eq "security"} -SearchBase "$OU" | Select -expand Name | Sort-Object


#Fill the list with the groupnames  
$AppGroupList | % { $ListApps.Items.Add($_) }
}


$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
    $form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
#region Generated Form Code
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 271
$System_Drawing_Size.Width = 284
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.Name = "form1"
$form1.Text = "Install Software - TEST OU"
$form1.add_Load($handler_form1_Load)


$radioButton3.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 188
$System_Drawing_Point.Y = 58
$radioButton3.Location = $System_Drawing_Point
$radioButton3.Name = "radioButton3"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 51
$System_Drawing_Size.Width = 88
$radioButton3.Size = $System_Drawing_Size
$radioButton3.TabIndex = 10
$radioButton3.TabStop = $True
$radioButton3.Text = "Load List of Computers"
$radioButton3.UseVisualStyleBackColor = $True
$radioButton3.add_CheckedChanged($handler_radioButton3_CheckedChanged)

$form1.Controls.Add($radioButton3)


$radioButton2.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 102
$System_Drawing_Point.Y = 54
$radioButton2.Location = $System_Drawing_Point
$radioButton2.Name = "radioButton2"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 58
$System_Drawing_Size.Width = 80
$radioButton2.Size = $System_Drawing_Size
$radioButton2.TabIndex = 9
$radioButton2.TabStop = $True
$radioButton2.Text = "Enter Hostname"
$radioButton2.UseVisualStyleBackColor = $True
$radioButton2.add_CheckedChanged($handler_radioButton2_CheckedChanged)

$form1.Controls.Add($radioButton2)


$radioButton1.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 59
$radioButton1.Location = $System_Drawing_Point
$radioButton1.Name = "radioButton1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 48
$System_Drawing_Size.Width = 76
$radioButton1.Size = $System_Drawing_Size
$radioButton1.TabIndex = 8
$radioButton1.TabStop = $True
$radioButton1.Text = "LocalHost"
$radioButton1.UseVisualStyleBackColor = $True
$radioButton1.add_CheckedChanged($handler_radioButton1_CheckedChanged)

$form1.Controls.Add($radioButton1)

$label3.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 9
$label3.Location = $System_Drawing_Point
$label3.Name = "label3"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 185
$label3.Size = $System_Drawing_Size
$label3.TabIndex = 7
$label3.Text = "SCCM Application Install Groups:-"

$form1.Controls.Add($label3)

$textHostname.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 140
$System_Drawing_Point.Y = 113
$textHostname.Location = $System_Drawing_Point
$textHostname.Name = "textHostname"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 27
$System_Drawing_Size.Width = 135
$textHostname.Size = $System_Drawing_Size
$textHostname.TabIndex = 6
$textHostname.Text = "Manual hostname entry"
$textHostname.add_TextChanged($handler_label2_Click)

$form1.Controls.Add($textHostname)

$txtHostname.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 113
$txtHostname.Location = $System_Drawing_Point
$txtHostname.Name = "txtHostname"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 124
$txtHostname.Size = $System_Drawing_Size
$txtHostname.TabIndex = 5
$txtHostname.add_MouseLeave($handler_textBox1_TextChanged)

$form1.Controls.Add($txtHostname)


$Install.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 181
$Install.Location = $System_Drawing_Point
$Install.Name = "Install"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 82
$System_Drawing_Size.Width = 269
$Install.Size = $System_Drawing_Size
$Install.TabIndex = 4
$Install.Text = "Install"
$Install.UseVisualStyleBackColor = $True
$Install.add_Click($Install_OnClick)

$form1.Controls.Add($Install)

$label1.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 140
$System_Drawing_Point.Y = 155
$label1.Location = $System_Drawing_Point
$label1.Name = "label1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 140
$label1.Size = $System_Drawing_Size
$label1.TabIndex = 3
$label1.Text = "Load computers from file"

$form1.Controls.Add($label1)


$Browse.DataBindings.DefaultDataSourceUpdateMode = 0

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 150
$Browse.Location = $System_Drawing_Point
$Browse.Name = "Browse"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 23
$System_Drawing_Size.Width = 124
$Browse.Size = $System_Drawing_Size
$Browse.TabIndex = 2
$Browse.Text = "Browse"
$Browse.UseVisualStyleBackColor = $True
$Browse.add_Click($Browse_OnClick)

$form1.Controls.Add($Browse)

$ListApps.DataBindings.DefaultDataSourceUpdateMode = 0
$ListApps.FormattingEnabled = $True
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 7
$System_Drawing_Point.Y = 32
$ListApps.Location = $System_Drawing_Point
$ListApps.Name = "ListApps"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 21
$System_Drawing_Size.Width = 269
$ListApps.Size = $System_Drawing_Size
$ListApps.TabIndex = 0

$form1.Controls.Add($ListApps)

#endregion Generated Form Code

#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

} #End Function


#Select File Explorer Function
function Select-FileDialog {

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Filter = "Csv files (*.csv)|*.csv|Txt files (*.txt)|*.txt|All files (*.*)|*.*"
$ofd = New-Object System.Windows.Forms.OpenFileDialog
$ofd.Filter = $Filter
$ofd.InitialDirectory = "c:\scripts"
$ofd.ShowHelp=$true
if($ofd.ShowDialog() -eq "OK") { $ofd.FileName }

} #End Function

#Test to see if ActiveDirectory module is install and if not run remote PSsession from domain controller
function load_module($name)
{ 
    if (-not(Get-Module -Name $name)) 
    {
        if (Get-Module -ListAvailable | Where-Object { $_.name -eq $name })
        {
            Import-Module $name  
            return $true
        }
        else
        {   
            return $false
        }
    }
    else
    {
        return $true
    }
}

$moduleName = "ActiveDirectory"

try 
{
    if (load_module $moduleName)
    {
        Write-Host "Loaded $moduleName module on localhost"
    }

    else
    {
        Write-Host "Failed to load $moduleName module"

        #Get Domain Controller name
        $ComputerInfo = get-wmiobject -class "Win32_NTDomain" -namespace "root\CIMV2"
        $DC = ($ComputerInfo[1].DomainControllerName).Replace(“\”,”")

        #Load remote PSsession from domain controller
        Write-Host "Loading remote PSsession to $DC"
        $Session = New-PSsession -Computername $DC
        Invoke-Command -Command {Import-Module "ActiveDirectory"} -Session $Session
        Import-PSSession -AllowClobber -Session $Session -DisableNameChecking -Module $moduleName | Out-Null

    }
}
catch 
{
    Write-Host "Exception caught: $_" 
}



#Call the Function
GenerateForm