Deployment.v1.4.ps1

<#PSScriptInfo
 
.VERSION 1.4
 
.GUID 631a5015-88a6-4506-856b-61e6fa80631f
 
.AUTHOR Arno Landwehr
 
.COMPANYNAME
 
.COPYRIGHT Arno Landwehr
 
.TAGS
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES Title: Powershell deployment tool
Writen by Arno Landwehr
20-06-2019
This Script can run Scripts, commands en installers on multiple Machines
The configuration in saved in Deployment.Config.xml
and each time the file is saved by the script a backup is created as Deployment.Config.xm_
this script uses the ADMIN$ share of windows and Invoke-command to run remote scripts
to pass credentials to the remote computer, the password is encrypted with a dynamicaly created key.
todo: cleanup, self removal of script not working correctly
 
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
 Powershell deployment tool
 
#>
 




function OnApplicationLoad {
Remove-Variable * -ErrorAction SilentlyContinue
$CreateXML = @"
<?xml version="1.0"?>
<OPTIONS Product="Deployment tool script" Version="1.3" SoftwareShare="" LogShare="">
<Defaults lastopenOU="OU=Computers,$Global:LocalDomain">
<catalog>
  <Script id="001">
    <ScriptName>Program 1</ScriptName>
    <ScriptLine>cmd.exe</ScriptLine>
    <ScriptChecked>True</ScriptChecked>
  </Script>
  <Script id="002">
    <ScriptName>Program 2</ScriptName>
    <ScriptLine>cmd.exe</ScriptLine>
    <ScriptChecked>False</ScriptChecked>
  </Script>
</catalog>
</Defaults>
</OPTIONS>
"@


        $global:Last_Sel = "Local Computer" 
        $Global:ReturnSrc = "localhost"
        $Root = [ADSI]"LDAP://RootDSE"
        $Global:LocalDomain = $Root.Get("rootDomainNamingContext")
        $Global:LocalDomainShort = $Global:LocalDomain -replace "DC=","" -replace ",","."         
        Add-Type -AssemblyName System.Windows.Forms
        Add-Type -AssemblyName System.Drawing    

    $XMLOptions = "Deployment.Config.xml"

    $Script:ParentFolder = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')
    $global:XMLFile = Join-Path $ParentFolder $XMLOptions
    
    $XMLMsg = "Configuration file $XMLOptions not detected in folder $ParentFolder. Would you like to create one now?"
    if(!(Test-Path $global:XMLFile)){
        if([System.Windows.Forms.MessageBox]::Show($XMLMsg,"Warning",[System.Windows.Forms.MessageBoxButtons]::YesNo) -eq "Yes")
            {
            $CreateXML | Out-File $global:XMLFile
            $TemplateMsg = "Opening XML configuration file for editing ($global:XMLFile). Please relaunch the script when the configuration is complete."
            [System.Windows.Forms.MessageBox]::Show($TemplateMsg,"Information",[System.Windows.Forms.MessageBoxButtons]::Ok) | Out-Null
            notepad $global:XMLFile
            Exit
             }
        else{Exit}
    }
    else{[XML]$global:xmldocument = Get-Content $global:XMLFile
                $Script:XML = $global:xmldocument.selectNodes("//Script")
                $max_scrpt_lngt2 = ($Script:XML.ScriptName | measure -Maximum -Property Length).Maximum | Out-String
                $array = foreach ($ID in $Script:XML) { [int](($ID | Select-Object -ExpandProperty ID)/1) }
                $global:high_id = $array | measure -Maximum | Select-Object -ExpandProperty Maximum
                $global:initialLDAP = $global:xmldocument.ChildNodes.selectNodes("/Defaults").lastopenOU
                $global:SoftwareShare = $global:xmldocument.ChildNodes.selectNodes("/OPTIONS ").SoftwareShare
                $global:LogShare = $global:xmldocument.ChildNodes.selectNodes("/OPTIONS ").LogShare
        }
    if($global:xmldocument.ChildNodes.selectNodes("/OPTIONS").Version -ne ([xml]$CreateXML).OPTIONS.Version)
        {
        $VersionMsg = "You are using an older version of the Options file. Please generate a new Options file and transfer your settings.`r`nIn Use: $($XML.Options.Version) `r`nLatest: $(([xml]$CreateXML).Options.Version)"
        [System.Windows.Forms.MessageBox]::Show($VersionMsg,"Warning",[System.Windows.Forms.MessageBoxButtons]::Ok)
        }
    else{}
    return $true#return true for success or false for failure
}    

function OnApplicationExit {
    $form1.Close()
    $script:ExitCode = 0 #Set the exit code for the Packager
}

Function Readpwd
{     Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName Microsoft.VisualBasic
    $form5 = New-Object System.Windows.Forms.Form
    $form5.Width = 500
    $form5.Height = 150
    $form5.Text = "Enter Password:"
    $form5.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $textLabel501 = New-Object System.Windows.Forms.Label
    $textLabel501.Left = 25
    $textLabel501.Top = 15
    $textLabel501.Text = "Enter Password:"
    $textBox501 = New-Object System.Windows.Forms.TextBox
    $textBox501.Left = 150
    $textBox501.Top = 12
    $textBox501.width = 200
    $textBox501.PasswordChar = '*'
    $button501 = New-Object System.Windows.Forms.Button
    $button501.Left = 250
    $button501.Top = 85
    $button501.Width = 75
    $button501.Text = "Ok" 
    $eventHandler501 = [System.EventHandler]{
    $textBox501.Text
    $form5.Close() }
    $button501.Add_Click($eventHandler501) 
    $form5.Controls.Add($button501)
    $form5.Controls.Add($textLabel501)
    $form5.Controls.Add($textBox501)
    $ret = $form5.ShowDialog()
    return $textBox501.Text
}


Function Executelines {
            $command = $null
    ForEach ($Machine in $global:Machines) {
    If ( $Machine -eq "localhost" ) {
            $command += "& "
            foreach ( $line in $global:xmldocument.selectNodes("//Script")) {
            if($line.Scriptchecked -eq "True") {
            $command += $Line.ScriptLine.tostring()
            $command += "`r`n"
            }}
            $sb = [scriptblock]::create($command)
            Invoke-Command -ScriptBlock $sb
            $sb = $null
            $command = $null
    }
    Else {    Set-ExecutionPolicy ByPass -Scope CurrentUser
            $key = [Convert]::ToBase64String((1..32 |% { [byte](Get-Random -Minimum 0 -Maximum 255) }))
            $User = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
            $ss = ConvertTo-SecureString (Readpwd) -AsPlainText -Force
            $es = ConvertFrom-SecureString -SecureString $ss -Key ([Convert]::FromBase64String($key))
            $es | out-file  -FilePath \\$Machine\admin$\temp\load.txt
            $command += "Function ConvertTo-UnsecureString {
Param ( [Parameter(Mandatory=`$True)]
    [System.Security.SecureString]`$ss )
Try {`$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToGlobalAllocUnicode(`$ss)
    [System.Runtime.InteropServices.Marshal]::PtrToStringUni(`$ptr)}
Finally {[System.Runtime.InteropServices.Marshal]::ZeroFreeGlobalAllocUnicode(`$ptr)}
                }
`$key = `"$key`"
`$es = get-content c:\windows\temp\load.txt
Remove-Item c:\windows\temp\load.txt
`$ss = ConvertTo-SecureString -String `$es -Key ([Convert]::FromBase64String(`$key))
`$password = ConvertTo-UnsecureString `$ss
`$date = (get-date).ToString('ddMMyy')
`$username = `"$User`"
net use $global:SoftwareShare /delete /y
net use $global:SoftwareShare /user:`$username `$password
`$env:SEE_MASK_NOZONECHECKS = 1`r`n"

            foreach ( $line in $global:xmldocument.selectNodes("//Script")) {
            if($line.Scriptchecked -eq "True") { $sb = $Line.ScriptLine.tostring() } 
            $Scriptblck = [scriptblock]::create($sb)
            $command += "`$result += invoke-command -scriptblock { $Scriptblck }"
            $command += "`r`n"
            }
            $command += "`$result | out-file -FilePath $global:LogShare\$Machine.`$date.log -Append"
            $command += "`r`n"
            $command += "Remove-Item env:\SEE_MASK_NOZONECHECKS
net use $global:SoftwareShare /delete /y
`$argumentsList = `"Remove-Item 'c:\windows\temp\deploy.ps1' -Force`"
Start-Process `"PowerShell.exe`" -ArgumentList `$argumentsList`r`n"

            $command | Out-File -width 1000 -FilePath \\$Machine\admin$\temp\deploy.ps1
            Invoke-Command -Computername $Machine -ScriptBlock { powershell.exe -file c:\windows\temp\deploy.ps1 }
            $sb = $null
            $command = $null
    
    
    }}}

Function Get-FileName($initialDirectory)
{   
    Add-Type -AssemblyName System.Windows.Forms

    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $initialDirectory
    $OpenFileDialog.Title = "Select CSV File"
    $OpenFileDialog.Multiselect = $False
    $OpenFileDialog.filter = "Csv File (*.csv)| *.csv"
    $OpenFileDialog.ShowDialog() | Out-Null
    $OpenFileDialog.filename
 } 

function RemoteComputer ($initialRemote)
{
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName Microsoft.VisualBasic
    $form2 = New-Object System.Windows.Forms.Form
    $form2.Width = 500
    $form2.Height = 150
    $form2.Text = "Enter Remote computer name"
    $form2.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $textLabel201 = New-Object System.Windows.Forms.Label
    $textLabel201.Left = 25
    $textLabel201.Top = 15
    $textLabel201.Text = "Remote Computer"
    $textBox201 = New-Object System.Windows.Forms.TextBox
    $textBox201.Left = 150
    $textBox201.Top = 12
    $textBox201.width = 200
    $textBox201.Text = $initialRemote
    $button201 = New-Object System.Windows.Forms.Button
    $button201.Left = 250
    $button201.Top = 85
    $button201.Width = 75
    $button201.Text = "Ok" 
    $eventHandler201 = [System.EventHandler]{
    $textBox201.Text
    $form2.Close() }
    $button201.Add_Click($eventHandler201) 
    $form2.Controls.Add($button201)
    $form2.Controls.Add($textLabel201)
    $form2.Controls.Add($textBox201)
    $ret = $form2.ShowDialog()
    return $textBox201.Text

}


function LDAP_Query ($global:initialLDAP)
{
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName Microsoft.VisualBasic
    $form3 = New-Object System.Windows.Forms.form
    $form3.Width = 500
    $form3.Height = 150
    $form3.Text = "Enter LDAP Query"
    $form3.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $textLabel301 = New-Object System.Windows.Forms.Label
    $textLabel301.Left = 25
    $textLabel301.Top = 15
    $textLabel301.Width = 70
    $textLabel301.Text = "LDAP Query"
    $textBox301 = New-Object System.Windows.Forms.TextBox
    $textBox301.Left = 100
    $textBox301.Top = 12
    $textBox301.width = 350
    $textBox301.Text = $global:initialLDAP
    $button301 = New-Object System.Windows.Forms.Button
    $button301.Left = 250
    $button301.Top = 85
    $button301.Width = 75
    $button301.Text = "Ok" 
    $eventHandler301 = [System.EventHandler]{
    $textBox301.Text
    $global:xmldocument.selectNodes("//Defaults").lastopenOU = $textBox301.Text.tostring()
    $form3.Close() }
    $button301.Add_Click($eventHandler301) 
    $form3.Controls.Add($button301)
    $form3.Controls.Add($textLabel301)
    $form3.Controls.Add($textBox301)
    $ret = $form3.ShowDialog()
    
    return $textBox301.Text
}

function SetOptions #(global:SoftwareShare, $global:LogShare)
{
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName Microsoft.VisualBasic
    $form4 = New-Object System.Windows.Forms.form
    $form4.Width = 500
    $form4.Height = 200
    $form4.Text = "Set Options"
    $form4.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $textLabel401 = New-Object System.Windows.Forms.Label
    $textLabel401.Left = 25
    $textLabel401.Top = 15
    $textLabel401.Width = 70
    $textLabel401.Text = "Software Share"
    $textBox401 = New-Object System.Windows.Forms.TextBox
    $textBox401.Left = 100
    $textBox401.Top = 12
    $textBox401.width = 350
    $textBox401.Text = $global:SoftwareShare
    $textLabel402 = New-Object System.Windows.Forms.Label
    $textLabel402.Left = 25
    $textLabel402.Top = 45
    $textLabel402.Width = 70
    $textLabel402.Text = "Log Share"
    $textBox402 = New-Object System.Windows.Forms.TextBox
    $textBox402.Left = 100
    $textBox402.Top = 42
    $textBox402.width = 350
    $textBox402.Text = $global:LogShare
    $button401 = New-Object System.Windows.Forms.Button
    $button401.Left = 250
    $button401.Top = 85
    $button401.Width = 75
    $button401.Text = "Ok" 
    $eventHandler401 = [System.EventHandler]{
    $textBox401.Text
    $textBox402.Text
    $global:xmldocument.OPTIONS.SoftwareShare = $textBox401.Text.tostring()
    $global:xmldocument.OPTIONS.LogShare = $textBox402.Text.tostring()
    $form4.Close() }
    $button401.Add_Click($eventHandler401) 
    $form4.Controls.Add($button401)
    $form4.Controls.Add($textLabel401)
    $form4.Controls.Add($textBox401)
    $form4.Controls.Add($textLabel402)
    $form4.Controls.Add($textBox402)
    $ret = $form4.ShowDialog()
    
    return $textBox401.Text, $textBox402.Text
}

Function Get-machines ($Global:returnLDAP)
{$Global:ReturnSrc = $null
$root = [ADSI]"LDAP://$Global:returnLDAP"
$search = [adsisearcher]$root
$Search.Filter = "(&(objectCategory=computer))"
$colResults = $Search.FindAll()
foreach ($i in $colResults)
{$computer = $i.GetDirectoryEntry()
$Global:ReturnSrc += @($computer.dNSHostName) }
Return $Global:ReturnSrc
}

Function GenerateProgramRow
{
 param(
        [Object[]]$Label
    )
    
    $CheckBox = New-Object System.Windows.Forms.CheckBox  
    $Textbox = New-Object System.Windows.Forms.TextBox
    $Textbox2 = New-Object System.Windows.Forms.TextBox
    $btnDel = New-Object System.Windows.Forms.Button
    $CheckBox.UseVisualStyleBackColor = $True
    $CheckBox.AutoSize = $True
    $CheckBox.Width = 35
    $CheckBox.Height = 24
    $CheckBox.TabIndex = $global:CheckBoxCounter + 4
    $LBLID = $Label.id.ToString()

    $CheckBox.Text = $Label.id.ToString()
    $Textbox.Text =  $Label.ScriptName

    $CheckBox.Name = "$LBLID"
    $Textbox.Name = "$LBLID"

    # Make sure to vertically space them dynamically, counter comes in handy
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 33
    $System_Drawing_Point.Y = 83 + (($global:CheckBoxCounter - 1) * 31)
    $System_Drawing_Point_btnDel = New-Object System.Drawing.Point
    $System_Drawing_Point_btnDel.x = 10
    $System_Drawing_Point_btnDel.y = $System_Drawing_Point.Y
    $System_Drawing_Point_text = New-Object System.Drawing.Point
    $System_Drawing_Point_text.Y = $System_Drawing_Point.Y
    $System_Drawing_Point_text.X = 80
    $Textbox2.Text = $Label.ScriptLine
    $Textbox2.Name = "$LBLID"
    $System_Drawing_Point_text2 = New-Object System.Drawing.Point
    $System_Drawing_Point_text2.Y = $System_Drawing_Point.Y
    $System_Drawing_Point_text2.X = 100 + ( $max_scrpt_lngt * 6 )
    $CheckBox.Location = $System_Drawing_Point
    $CheckBox.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation 

    $btnDel.Location = $System_Drawing_Point_btnDel
    $btnDel.Name = "$LBLID"
    $btnDel.Size = '18, 18'
    $btnDel.TabIndex = 5
    $btnDel.Text = ""
    $btnDel.Image = $global:image
    $btnDel.UseVisualStyleBackColor = $True
    $btnDel.add_Click($ChangeHandler4)
    
    
    $Textbox.location = $System_Drawing_Point_text
    $Textbox.Width = ( $max_scrpt_lngt * 6 )
    $Textbox.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation 
    $Textbox2.location = $System_Drawing_Point_text2
    $Textbox2.Width = 500
    $Textbox2.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation 
    $TextBox.add_TextChanged($ChangeHandler2)
    $TextBox2.add_TextChanged($ChangeHandler3)

        if($Label.Scriptchecked -eq "True")
            {$CheckBox.Checked=1
            }
        else
            {$CheckBox.Checked=0
            }
        $CheckBox.Add_CheckStateChanged($ChangeHandler1)

    # Add it to the form
    $form1.Controls.Add($btnDel)    
    $form1.AcceptButton = $btnDel
    $form1.Controls.Add($CheckBox)
    $form1.Controls.Add($Textbox)
    $form1.Controls.Add($Textbox2)
}

function GenerateForm
{
  
$form1 = New-Object system.Windows.Forms.Form
$form1.Text = "Script Deployer"
$form1.Name = "form1"

$form1.AutoSize = $True
$form1.AutoSizeMode = "GrowAndShrink"
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
  
$global:XML_Lines = $global:xmldocument.selectNodes("//Script")

$iconBase64      = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAQABADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD6l+MHxFs4/ic2nfEnxtc/DTwEF8u28PxN/pmv+XKVNyZoEZ4LdmZVCCQPIAMhMkN2v7P/AI2/4XNq3ijxbbePotf0221F7Ky0nRBtsLe2CqY2k8yFZGnkB8xvmIUMqqeCW8p/bq0XUm8c/DzXNP0DWtciWFoLhtH0ye98kRatpN0N4iRtuY4LgjPXZgV0f/BPXw3f+G/hHq76ppOo6NeXF/aQ+RqllLaTFYNJsLcnZIobHmRS4PTrimB//9k='
$iconBytes       = [Convert]::FromBase64String($iconBase64)
$stream          = New-Object IO.MemoryStream($iconBytes, 0, $iconBytes.Length)
$stream.Write($iconBytes, 0, $iconBytes.Length);
$iconImage       = [System.Drawing.Image]::FromStream($stream, $true)

$global:image = [System.Drawing.Icon]::FromHandle((New-Object System.Drawing.Bitmap -Argument $stream).GetHIcon())

#Messure lenght longest ScriptName
$max_scrpt_lngt = ( @(foreach($Label in $global:XML_Lines){ $label.ScriptName }) | Measure-Object -Maximum -Property Length).Maximum

# Keep track of number of checkboxes
$global:CheckBoxCounter = 1

$ChangeHandler1 = { 
$target = ($global:xmldocument.selectNodes("//Script")|where {$_.id -eq $this.name})
$target.ScriptChecked = $this.checked.tostring()
$target = $null
 }
$ChangeHandler2 = { 
$target = ($global:xmldocument.selectNodes("//Script")|where {$_.id -eq $this.name})
$target.Scriptname = $this.text
$target = $null
}
$ChangeHandler3 = { 
$target = ($global:xmldocument.selectNodes("//Script")|where {$_.id -eq $this.name})
$target.Scriptline = $this.text
$target = $null
 }
$ChangeHandler4 = { 
$targetform = $form1.Controls | Where-Object {$_.Name -eq $this.name}
ForEach ( $formobj in $targetform ) {$form1.Controls.remove($formobj) }
$form1.Refresh()

$target = ($global:xmldocument.selectNodes("//Script")|where {$_.id -eq $this.name})
while ($target -ne $null) {
    $target.ParentNode.RemoveChild($target)
    $target = ($global:xmldocument.selectNodes("//Script")|where {$_.id -eq $this.name})}
$target = $null
 }
 

$CheckBoxes = foreach($Label in $global:XML_Lines ) {

if ($Label.id -ne $null){
        
    GenerateProgramRow $Label

    # increment our counter
    $global:CheckBoxCounter++
    $InitialFormWindowState = $form1.WindowState
    
}
}

#Dropdown menu
$DropDownBox_SelectedIndexChanged = {

    $Choice = $DropDownBox.SelectedItem.ToString()
        if ($choice -eq "Local Computer") 
        {
        $global:Last_Sel = "Local Computer" 
        $global:Machines = "localhost"
        $StatusSelected.Text = $global:Last_Sel," : ",$global:Machines
        }
        elseif ($choice -eq "Remote Computer") 
        {$global:Machines = $null
        if ($Global:returnRemote -eq $null) {$initialRemote = "Server1.$Global:LocalDomainShort"} else {$initialRemote = $Global:returnRemote}
        $Global:returnRemote = RemoteComputer $initialRemote
        $global:Last_Sel = "Remote Computer"
        $global:Machines = $Global:returnRemote
        $StatusSelected.Text = $global:Last_Sel," : ",$global:Machines
        }
        elseif ($choice -eq "LDAP Query") 
        { $global:Machines = $null
        $global:initialLDAP = $Global:returnLDAP
        $Global:returnLDAP = LDAP_Query $global:initialLDAP
        $global:Last_Sel = "LDAP Query"
        $Global:ReturnSrc = $Global:returnLDAP
        $StatusSelected.Text = $global:Last_Sel," : ",$Global:ReturnSrc
        $global:Machines = Get-machines $Global:returnLDAP
        }

        elseif ($choice -eq "CSV File") 
        {$global:Machines = $null
        if ($Global:returnFile -eq $null) {$initialDirectory = "$Script:ParentFolder\coputerlist.csv"} else {$initialDirectory= $Global:returnFile}
        $Global:returnFile = Get-FileName $initialDirectory
        $global:Last_Sel = "CSV File"
        $Global:ReturnSrc = $Global:returnFile
        $StatusSelected.Text = $global:Last_Sel," : ",$Global:ReturnSrc
        $CSV = Import-Csv $Global:returnFile
        ForEach ($Entry in $CSV) {
        $global:Machines += @($Entry.name)}
        }        
}



    $DropDownBox = new-object System.Windows.Forms.ComboBox
    $System_Drawing_Point_DropDownBox = New-Object System.Drawing.Point
    $System_Drawing_Point_DropDownBox.x = 17
    $System_Drawing_Point_DropDownBox.y = 13
    $DropDownBox.Location = $System_Drawing_Point_DropDownBox
    $DropDownBox.size = new-object System.Drawing.Size(100,25)
    $DropDownBox.Text = "Select Source"
    $DropDownBox.Items.Add("Local Computer")
    $DropDownBox.Items.Add("Remote Computer")
    $DropDownBox.Items.Add("LDAP Query")
    $DropDownBox.Items.Add("CSV File")
    $DropDownBox.add_SelectedIndexChanged($DropDownBox_SelectedIndexChanged)


# Options Button
    $btnOptions_Click={
    SetOptions $global:SoftwareShare, $global:LogShare
}    


    $System_Drawing_Point_btnOptions = New-Object System.Drawing.Point
    $btnOptions = New-Object System.Windows.Forms.Button
    $btnOptions.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Point_btnOptions.x = 447
    $System_Drawing_Point_btnOptions.y = 13
    $btnOptions.Location = $System_Drawing_Point_btnOptions
    $btnOptions.Name = "btnOptions"
    $btnOptions.Size = '75, 20'
    $btnOptions.TabIndex = 4
    $btnOptions.Text = "Options"
    $btnOptions.UseVisualStyleBackColor = $True
    $btnOptions.add_Click($btnOptions_Click)


# Exit Button
    $btnExit_Click={
    OnApplicationExit
}    


    $System_Drawing_Point_btnExit = New-Object System.Drawing.Point
    $btnExit = New-Object System.Windows.Forms.Button
    $btnExit.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Point_btnExit.x = 367
    $System_Drawing_Point_btnExit.y = 13
    $btnExit.Location = $System_Drawing_Point_btnExit
    $btnExit.Name = "btnExit"
    $btnExit.Size = '75, 20'
    $btnExit.TabIndex = 4
    $btnExit.Text = "Exit"
    $btnExit.UseVisualStyleBackColor = $True
    $btnExit.add_Click($btnExit_Click)

# Save Button
    $btnSave_Click={
    Copy-Item -Path $global:XMLFile -Destination ($global:XMLFile -replace 'xml','xm_')

    $global:xmldocument.Save($global:XMLFile)    
}    

    $System_Drawing_Point_btnSave = New-Object System.Drawing.Point
    $btnSave = New-Object System.Windows.Forms.Button
    $btnSave.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Point_btnSave.x = 207
    $System_Drawing_Point_btnSave.y = 13
    $btnSave.Location = $System_Drawing_Point_btnSave
    $btnSave.Name = "btnSave"
    $btnSave.Size = '75, 20'
    $btnSave.TabIndex = 2
    $btnSave.Text = "Save"
    $btnSave.UseVisualStyleBackColor = $True
    $btnSave.add_Click($btnSave_Click)    

    
# Add Button
    $btnAdd_Click={
    $global:high_id++
    $high_id = ($global:high_id).ToString("000")
    $Label = $global:xmldocument.OPTIONS.Defaults.catalog.Script[0].Clone()
    $Label.id = [string]($high_id)
    [Void]$global:xmldocument.OPTIONS.Defaults.catalog.AppendChild($Label)
    GenerateProgramRow $Label
    $System_Drawing_Size.Width = 650 + ( $max_scrpt_lngt * 5 )
    $System_Drawing_Size.Height = 136  + (($global:CheckBoxCounter - 1) * 31)
    $form1.ClientSize = $System_Drawing_Size
    $global:CheckBoxCounter++
    $global:XML_Lines += $Label

    
}    

    $System_Drawing_Point_btnAdd = New-Object System.Drawing.Point
    $btnAdd = New-Object System.Windows.Forms.Button
    $btnAdd.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Point_btnAdd.x = 287
    $System_Drawing_Point_btnAdd.y = 13
    $btnAdd.Location = $System_Drawing_Point_btnAdd
    $btnAdd.Name = "btnAdd"
    $btnAdd.Size = '75, 20'
    $btnAdd.TabIndex = 3
    $btnAdd.Text = "Add"
    $btnAdd.UseVisualStyleBackColor = $True
    $btnAdd.add_Click($btnAdd_Click)

        
# Execute Button
    $btnExecute_Click={ Executelines }
    

    $System_Drawing_Point_btnExecute = New-Object System.Drawing.Point
    $btnExecute = New-Object System.Windows.Forms.Button
    $System_Drawing_Point_btnExecute.x = 127
    $System_Drawing_Point_btnExecute.y = 13
    $btnExecute.Location = $System_Drawing_Point_btnExecute
    $btnExecute.Name = "btnExecute"
    $btnExecute.Size = '75, 20'
    $btnExecute.TabIndex = 1
    $btnExecute.Text = "Execute"
    $btnExecute.UseVisualStyleBackColor = $True
    $btnExecute.add_Click($btnExecute_Click)
    
# Status textblock
    $StatusSelected = New-Object System.Windows.Forms.TextBox
    $StatusSelected.Location = New-Object System.Drawing.Point(17,43)
    $StatusSelected.name = "Status"
    $StatusSelected.ReadOnly = $True
    $StatusSelected.Size = New-Object System.Drawing.Size(500,25)
    $StatusSelected.Text = $global:Last_Sel," : ",$Global:ReturnSrc
    $form1.Controls.Add($StatusSelected)

    
# Add it to the form
    $Form1.Controls.Add($DropDownBox)
    $form1.Controls.Add($btnExecute)    
    $form1.AcceptButton = $btnExecute
    $form1.Controls.Add($btnOptions)    
    $form1.AcceptButton = $btnOptions
    $form1.Controls.Add($btnExit)    
    $form1.AcceptButton = $btnExit
    $form1.Controls.Add($btnAdd)    
    $form1.AcceptButton = $btnAdd
    $form1.Controls.Add($btnSave)    
    $form1.AcceptButton = $btnSave
    $form1.Controls.Add($listBox)
    $form1.Controls.Add($StatusSelected)

    #
    $form1.Activate()
    $form1.Refresh
    $InitialFormWindowState = $form1.WindowState


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

#----------------------------------------------
#region Generated Form Code
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 650 + ( $max_scrpt_lngt * 5 )
$System_Drawing_Size.Height = 136  + (($global:CheckBoxCounter - 1) * 31)
$form1.ClientSize = $System_Drawing_Size


#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
}

#Call OnApplicationLoad to initialize
if((OnApplicationLoad) -eq $true)
{
$global:Labelw = @()
    #Call the Functionform
GenerateForm 
OnApplicationExit
}