0

I have a set of files that represent export of Active Directory security groups members. These files contain user email addresses. I would like to use PowerShell to scan all the files (~300) and by using Get-ADUser cmdlet find user account names based on the email addresses stored in these files and then save the output in new files in another folder.

I could of course do a different AD export and fetch user account names instead of email addresses, but it wouldn't be helpful in this case, because I'm working on porting user access permissions from one AD domain to another AD domain (without any trust between the two) and the only thing that was done to help me is that in the old domain the user accounts were modified to contain email addresses from the new domain, hence the email addresses match in both old and new domain, and as I now have a text file per AD group with email addresses in them matching the new domain, I can use these addresses to fetch users' new account names from the new domain.

So far I was able to list the files and do the email to account name mapping using the following code:

$directory = 'c:\temp\groups\all'

$files = Get-ChildItem -Path $directory -File *.txt -Recurse | Select -expand fullname

ForEach ($file in $files) 
{
  Get-Content $file |ForEach-Object 
      {Get-ADUser -Filter {mail -like $_} -properties mail | Select-Object SamAccountName}
}

However, right now I'm stuck trying to figure out how to output the changes back into text files that would have the same name as originals, but be placed in a different folder.

I'm sure the code above can be made better; please bear with me, I'm beginner.

halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

-1

I hope I understood your question properly that you want to create a new file for each group in a new folder path.
These files should contain the SamAccountName and the email address of the user and each file should have the same name as the input file.

In that case, try:

$directory  = 'c:\temp\groups\all'
$targetPath = 'C:\temp\groups\accounts'

# create the target directory if not already exists
$null = New-Item -Path $targetPath -ItemType Directory -Force

# get a list of your input files
$files = Get-ChildItem -Path $directory -File -Filter *.txt -Recurse

foreach ($file in $files) {
    # read the file, skip empty or whitespace-only lines and skip the first two lines
    # loop trhough the content and collect the wanted objects in variable $group
    $group = Get-Content -Path $file.FullName | Where-Object { $_ -match '\S' } | 
             Select-Object -Skip 2 | ForEach-Object {
        $mail = $_.Trim()
        # try and find a user with this email address
        # the -Filter parameter actually takes a string
        $user = Get-ADUser -Filter "mail -like '$mail'" -Properties mail
        if ($user) {
            # output an object with both email address and SamAccountName
            $user | Select-Object SamAccountName, mail
        }
        else {
            # output a similar object where SamAccountName contains 'User Not Found'
            [PsCustomObject]@{SamAccountName = 'User Not Found'; mail = $mail }
        }
    }
    # now export the result to a new (csv) file in the target directory with the same name as the input file
    $targetFile = Join-Path -Path $targetPath -ChildPath ('(0}.csv' -f $file.BaseName)
    $group | Export-Csv -Path $targetFile -NoTypeInformation -UseCulture
}
  • By creating CSV file, you can keep properties for each user together, which is much more informative that single lines with just one property in text files.
  • The -UseCulture switch on Export-Csv makes sure the csv uses delimiter characters that your locally installed Excel expects, so you can simply double-click these files to open in Excel if you want.
Theo
  • 57,719
  • 8
  • 24
  • 41