Output data from ForEach loop inside button!

Welcome Forums General PowerShell Q&A Output data from ForEach loop inside button!

Viewing 3 reply threads
  • Author
    Posts
    • #188275
      Participant
      Topics: 3
      Replies: 2
      Points: 47
      Rank: Member

      Hi guys,

      I've created a new user script and added a 'bulk create' button. When clicked it reads a .csv, matches the field data with the parameters and creates users. I can't find a way to actually export the Username/ Password after it creates them though... I've looked everywhere, tried just about everything and now i'm stuck.
      Any ideas?!

      Thanks

      ### Bulk Creation button
      $BulkCreateButton = New-Object System.Windows.Forms.Button
      $BulkCreateButton.Location = New-Object System.Drawing.Size(490, 10)
      $BulkCreateButton.Size = New-Object System.Drawing.Size(75,23)
      $BulkCreateButton.Text = "Bulk Create"
      $main_form.Controls.Add($BulkCreateButton)
      $BulkCreateButton.Add_Click(
      {

      $Users = Import-Csv -Path "C:\Local Store\list.csv"

      foreach ($User in $Users)
      {
      $FirstName = $User.FirstName
      $LastName = $User.LastName

      ### Declare the variables for the account properties
      $template = $User.Template
      $SAMAccountName = $FirstName.Substring(0, [Math]::Min($LastName.Length, 1)) + $LastName
      $Name = $FirstName + " " + $LastName
      $Description = $User.Description
      $DisplayName = $Lastname + ", " + $FirstName + " " + $Description
      $HomeDirectory = "\\Bleh\Users\Userdata-4\" + $SAMAccountName
      $HomeDrive = "H"
      $EmployeeStartDate = get-date -Format dd/MM/yyyy
      $Manager = get-aduser -Identity $User.Manager | select distinguishedName
      $Country = "GB"
      $TargetOU = 'OU=Users,OU=Bleh'
      $UserEnabled = $true
      $PWNeverExpires = $false
      $CannotChangePW = $false
      $Password = "Jupiter12", "Rainbow75", "Waterfall45", "Daylight89", "Nightfall23" | get-random

      ### This selects the properties of the template to copy to our new user
      $TemplateToCopy = Get-Aduser $template -Properties memberOf, description, Office, Title, Department, Company

      ### This checks if the username already exists, if so it adds a '1'
      If (get-aduser $name) {$name=$name + "1"}
      If (get-aduser $SAMAccountName) {$SAMAccountName=$SAMAccountName + "1"}

      ### Declare below variable after SAMAccountName creation to create correct UserLogonName
      $UserLogonName = $FirstName + "." + $SAMAccountname.substring(1) + "@bleh.com"
      $EmailAddress = $UserLogonName

      ### Sets the parameters below to the new user account
      $params = @{'SamAccountName' = $SAMAccountName;
      'Instance' = $TemplateToCopy;
      'DisplayName' = $DisplayName;
      'GivenName' = $FirstName;
      'SurName' = $LastName;
      'PasswordNeverExpires' = $PWNeverExpires;
      'ChangePasswordAtLogon'= $True;
      'CannotChangePassword' = $CannotChangePW;
      'HomeDirectory' = $HomeDirectory;
      'HomeDrive' = $HomeDrive;
      'Description' = $Description;
      'Country' = $Country;
      'EmailAddress' = $EmailAddress;
      'Enabled' = $UserEnabled;
      'UserPrincipalName' = $UserLogonName;
      'AccountPassword' = (ConvertTo-SecureString -AsPlainText $Password -Force);
      }

      ### Creates the new user account
      New-ADUser -Name $Name @params

      ### Mirror all the groups the original account was a member of
      $TemplateToCopy.Memberof | % {Add-ADGroupMember $_ $SAMAccountName}

      ### Move the new user account into the assigned OU
      Get-ADUser $SAMAccountName| Move-ADObject -TargetPath $TargetOU
      Set-ADUser $SAMAccountName -replace @{'EmployeeStartDate' = $EmployeeStartDate}
      Set-ADUser $SAMAccountName -replace @{'personalTitle' = $User.TIA}
      Set-ADUser $SAMAccountName -manager $manager

      ### Create H:\ drive for user
      New-Item -Path "\\bleh.com\Users\Userdata-4\" -Name $SAMAccountName -ItemType Directory -ErrorAction SilentlyContinue
      ### Set Permissions on home folder
      $aclPath = "\\bleh.com\Users\Userdata-4\$SAMAccountName"
      $acl = Get-Acl $aclPath
      $identity = "bleh\$SAMAccountName"
      $rights = "Modify"
      $inheritanceFlags = "ContainerInherit, ObjectInherit"
      $propagationFlags = "None"
      $accessControlType = "Allow"
      $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$identity","$rights","$inheritanceFlags","$propagationFlags","$accessControlType")
      $acl.AddAccessRule($rule)
      Set-Acl $aclPath $acl

      ### Display Username/ Password in fields
      $UsernameTB.Text = $SAMAccountName
      $PasswordTB.Text = $Password

      }
      }
      )

    • #188305
      Participant
      Topics: 0
      Replies: 26
      Points: 124
      Helping Hand
      Rank: Participant

      Just try this option

      Create an array outside of the button click event and define it in the script scope.

      $Script:UserCredentials = @()
      

      After assigning the password variable, create a hash table with user name and password.

      $Password = "Jupiter12", "Rainbow75", "Waterfall45", "Daylight89", "Nightfall23" | get-random
      $Script:UserCredentials += @{
          UserName = $FirstName
          Password = $Password
      }
      

      Once you are out of the click event, before closing your form, access $Script:UserCredentials array and loop through each item to display/output the values.

      This option worked for me.

    • #188308
      Participant
      Topics: 9
      Replies: 1277
      Points: 1,051
      Helping Hand
      Rank: Community Hero

      The way that your code is written you would only ever get the last user created because it's in your FOR loop. If you want to support true "bulk" operations, you need to leverage the existing data and output everything back to a CSV rather than attempt to place everything in a control, IMHO. See this example:

      #Object to mock import of CSV
      $csv = @()
      $csv += [pscustomobject]@{FirstName = 'John';LastName='Smith'}
      $csv += [pscustomobject]@{FirstName = 'Julie';LastName='Thompson'}
      
      
      $results = foreach ($user in $csv) {
          $samAccountName = '{0}{1}' -f $user.FirstName.SubString(0,1), $user.LastName.SubString(0,4)
          $password = 'P@ssword1!','P@ssword2!','P@ssword3!' | Get-Random -Count 1
          #Provision
      
          $user | 
          Select *,
                 @{Name='SamAccountName';Expression={$SamAccountName}},
                 @{Name='Password';Expression={$Password}}
      
      
      }
      
      $results #| Export-Csv -Path C:\BulkImportResults.csv -NoTypeInformation
      

      Output:

      FirstName LastName SamAccountName Password  
      --------- -------- -------------- --------  
      John      Smith    JSmit          P@ssword3!
      Julie     Thompson JThom          P@ssword1!
      

      Also, you really need to add error handling and a status message so if an error occurs with a user you can see who failed and why they failed.

    • #188311
      Participant
      Topics: 3
      Replies: 2
      Points: 47
      Rank: Member

      Just try this option

      Create an array outside of the button click event and define it in the script scope.

      1
      2
      $Script:UserCredentials = @()
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      After assigning the password variable, create a hash table with user name and password.

      PowerShell
      6 lines

      1
      2
      3
      4
      5
      6
      $Password = "Jupiter12", "Rainbow75", "Waterfall45", "Daylight89", "Nightfall23" | get-random
      $Script:UserCredentials += @{
      UserName = $FirstName
      Password = $Password
      }
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      Once you are out of the click event, before closing your form, access $Script:UserCredentials array and loop through each item to display/output the values.

      This option worked for me.

      You are a genius THANK YOU!!

Viewing 3 reply threads
  • You must be logged in to reply to this topic.