none
Catch errors on get-content | foreach-object { get-aduser ... RRS feed

  • Question

  • Hello peeps.

    Hoping someone can help me.

    I'm building a script for the service desk to add hundreds of people to a group. 

    I'm probably going a long way around doing this but it does what I need it to do and I'm not that advanced at scripting (yet!?) 

    This is what I have so far:

    #   This function is the building bricks of the pop-up box for the several user accounts.
    #   It's copied from the website below. I've removed the help file tags purely to keep the script tidy for you. for further help and information visit the site.
    #   http://blog.danskingdom.com/powershell-multi-line-input-box-dialog-open-file-dialog-folder-browser-dialog-input-box-and-message-box/
    
    function Read-MultiLineInputBoxDialog([string]$MESSAGE, [string]$WINDOWTITLE, [string]$DEFAULTTEXT)
    {
        Add-Type -AssemblyName System.Drawing
        Add-Type -AssemblyName System.Windows.Forms
         
        # Create the Label.
        $LABEL = New-Object System.Windows.Forms.Label
    # this indent makes the text headline
        $LABEL.Location = New-Object System.Drawing.Size(10,20) 
        $LABEL.Size = New-Object System.Drawing.Size(280,20)
        $LABEL.AutoSize = $TRUE
        $LABEL.Text = $MESSAGE
         
        # Create the TextBox used to capture the user's text.
        $TEXTBOX = New-Object System.Windows.Forms.TextBox 
        $TEXTBOX.Location = New-Object System.Drawing.Size(50,50)
    # this indent sets the position of the text box
        $TEXTBOX.Size = New-Object System.Drawing.Size(525,180)
        $TEXTBOX.AcceptsReturn = $TRUE
        $TEXTBOX.AcceptsTab = $FALSE
        $TEXTBOX.Multiline = $TRUE
        $TEXTBOX.ScrollBars = 'Both'
        $TEXTBOX.Text = $DEFAULTTEXT
         
        # Create the OK button.
        $OKBUTTON = New-Object System.Windows.Forms.Button
        $OKBUTTON.Location = New-Object System.Drawing.Size(415,250)
        $OKBUTTON.Size = New-Object System.Drawing.Size(75,25)
        $OKBUTTON.Text = "OK"
        $OKBUTTON.Add_Click({ $FORM.Tag = $TEXTBOX.Text; $FORM.Close() })
         
        # Create the Cancel button.
        $CANCELBUTTON = New-Object System.Windows.Forms.Button
        $CANCELBUTTON.Location = New-Object System.Drawing.Size(510,250)
        $CANCELBUTTON.Size = New-Object System.Drawing.Size(75,25)
        $CANCELBUTTON.Text = "Cancel"
        $CANCELBUTTON.Add_Click({ $FORM.Tag = $NULL; $FORM.Close() })
         
        # Create the form.
        $FORM = New-Object System.Windows.Forms.Form 
        $FORM.Text = $WINDOWTITLE
        $FORM.Size = New-Object System.Drawing.Size(610,320)
        $FORM.FormBorderStyle = 'FixedSingle'
        $FORM.StartPosition = "CenterScreen"
        $FORM.AutoSizeMode = 'GrowAndShrink'
        $FORM.Topmost = $TRUE
        $FORM.AcceptButton = $OKBUTTON
        $FORM.CancelButton = $CANCELBUTTON
        $FORM.ShowInTaskbar = $TRUE
         
        # Add all of the controls to the form.
        $FORM.Controls.Add($LABEL)
        $FORM.Controls.Add($TEXTBOX)
        $FORM.Controls.Add($OKBUTTON)
        $FORM.Controls.Add($CANCELBUTTON)
         
        # Initialize and show the form.
        $FORM.Add_Shown({$FORM.Activate()})
        $FORM.ShowDialog() > $NULL   # Trash the text of the button that was clicked.
         
        # Return the text that the user entered.
        return $FORM.Tag
    }
    
    
    #   ------------------------------------- GRAB USER ID ---------------------------------------------
    
    $INPUTBOX = Read-MultiLineInputBoxDialog -Message "Enter the list of usernames below" -WindowTitle "I AM A BOX!!   LOLZ & ROFFLECOPTORZ!!" -DefaultText ""
    if ($INPUTBOX -eq $NULL) 
       { "You clicked Cancel" ; "The only thing to do now is exit" ; start-sleep 2 ; exit }
    else 
       { write-host ""
       write-host "This is the list of user names" -BackgroundColor Gray -ForegroundColor Blue
       start-sleep 1
       write-host ""
       # write-host $INPUTBOX 
       }
    
    $INPUTBOX | Out-File C:\users\graham\Desktop\exporttxt.txt -Encoding Ascii
    
    $1 = Get-Content C:\Users\graham\Desktop\exporttxt.txt | ForEach-Object { Get-ADUser -filter 'name -eq $_' } | foreach { $_.samaccountname }
    
    $2 = Get-Content C:\Users\graham\Desktop\exporttxt.txt | ForEach-Object { Get-ADUser -filter 'samaccountname -eq $_' } | foreach { $_.samaccountname }
    
    
    
    try { 
        Get-Content C:\Users\graham\Desktop\exporttxt.txt | ForEach-Object { Get-ADUser -Identity $_ } 
        }
    catch { "one or more user does not exist" }

    The above is clever enough to work out if a username or full name has been detected. I can add these users to the group without problem.

    Is there anyway of capturing dodgy names? Be it bad spelling or the user no longer exists? I have little faith in the service desk being able to capture a complete list of users, but want to make sure I can fire back a "these don't exist" file when I'm done.

    Thanks for your time. 

    Wednesday, July 1, 2015 3:58 PM

Answers

All replies

  • Hi Graham,

    Here's an example you can play with:

    Get-Content .\userList.txt | ForEach {
    
        $user = $_
    
        try {
    
            Get-ADUser -Identity $user -ErrorAction Stop | 
                Select -ExpandProperty SamAccountName
    
        } catch {
    
            Write-Host "Error checking $user" -ForegroundColor Red
            $user | Out-File .\usersToCheck.txt -Append
    
        }
    
    }
    
    
    
    userList.txt:
    tester1
    tester2
    noexist
    tester3
    noexist2


    Don't retire TechNet! - (Don't give up yet - 13,225+ strong and growing)

    Wednesday, July 1, 2015 4:08 PM
  • You sir, are a hero. 

    Thank you so much. Really appreciate it and the speed of your response. 

    Thursday, July 2, 2015 8:42 AM
  • Sorry to be a pain.

    So yours works based on the username, I'm trying to extend it to full name as well. 

    I tried to user a ('name -eq $_') -or ('sammacountname -eq $_') but it didn't go down so well so I figured another method would be to re-import the dead file and traverse the list again then export what would be a final dead file.

    Get-Content C:\Users\graham\Desktop\export.txt | ForEach { $user = $_
    
        try { Get-ADUser -Identity $user -ErrorAction Stop | Select -ExpandProperty SamAccountName 
            $user | out-file C:\users\graham\Desktop\working.txt -Append
            } 
        catch { Write-Host "Error checking $user" -ForegroundColor Red 
        $user | Out-File C:\Users\graham\Desktop\dead.txt -Append }
    
    }
    
    
    "this is where the first get-content ends"
    
    Get-Content C:\Users\graham\Desktop\dead.txt | ForEach { $name = $_
    
        try { Get-ADUser -filter 'name -eq $name' | Select -ExpandProperty SamAccountName | out-file C:\users\graham\Desktop\working.txt -Append
            } 
        catch { Write-Host "Error checking $name" -ForegroundColor Red 
        $name | Out-File C:\Users\graham\Desktop\deadforreal.txt -Append }
        
    }

    Whilst it amends the working file without a problem it doesn't export a list of deadforreal users.

    Any suggestions on where I'm going wrong? 

    Thanks again


    Thursday, July 2, 2015 10:23 AM
  • Hi Graham,

    Sorry for not responding earlier, I lost this thread.

    Here's an updated example (with limited error checking) that can test using the name or the username property:

    Get-Content .\userList.txt | ForEach {
    
        $user = $_
    
        try {
    
            $acc = Get-ADUser -Filter "SamAccountName -eq '$user' -or Name -eq '$user'" -ErrorAction Stop | 
                Select -ExpandProperty SamAccountName
    
            If ($acc.Count -gt 1) { 
    
                Write-Host "$user returned multiple results, verify the input." -ForegroundColor Red
                "$user - multiple results" | Out-File .\usersToCheck.txt -Append
    
            } 
            
            ElseIf ($acc) {
    
                $acc
                
            }
            
            Else {
    
                throw
    
            }
    
        } catch {
    
            Write-Host "Error checking $user" -ForegroundColor Red
            $user | Out-File .\usersToCheck.txt -Append
    
        }
    
    }
    
    
    userList.txt:
    testac1
    testac2
    noexist
    testac3
    noexist2
    Test Account 5
    Test Account 6
    noexist3
    Does Not Exist
    testac9
    
    usersToCheck.txt:
    noexist
    noexist2
    noexist3
    Does Not Exist
    testac9 - multiple results
    
    **Note: testac9 matched two users. One with a SamAccountName of testac9 and another with a name of testac9. Unlikely, but possible.

    Just as a note, this tests the 'name' property, not the 'DisplayName'. You can adjust the filter if you need to.


    Don't retire TechNet! - (Don't give up yet - 13,225+ strong and growing)

    Sunday, July 5, 2015 11:24 PM
  • Hi Mike,

    Thanks again for your response.

    I couldn't get it to work myself though not sure why. I had a play around and managed to get it working albeit the long way round I'm sure.

    get-content "Names.txt" | foreach {
       if ( Get-ADUser -Filter { sAMAccountName -eq $_ } ) 
          { Write-Host "$_ found in AD"
          $_ | Out-File "\\Names_alive.txt" -Append }
       else { Write-Host "$_" -ForegroundColor Red -NoNewline
          write-host " does not exist in AD"
          $_ | Out-File "Names_dead_start.txt" -Append }
     }
    
    ""
    
    "Let me check those none existent accounts for usernames"
    
    ""
    
    get-content "Names_dead_start.txt" | foreach {
       if ( Get-ADUser -Filter { Name -eq $_ } ) 
          { Write-Host "$_ found in AD"
          Get-ADUser -Filter { Name -eq $_ } | select -ExpandProperty SamAccountName | Out-File "Names_alive.txt" -Append }
       else { Write-Host "$_" -ForegroundColor Red -NoNewline
          write-host " does not exist in AD"
          $_ | Out-File "Names_dead.txt" -Append }
     }
    

    Once again, grateful for your input. Led me to an answer of sorts. 

    Tuesday, July 7, 2015 9:18 AM