Newbie looking for some help...Get-ADComputer

Hi, I have a task to look for computers in all 25 different computer OUs for computers with no description and then email the result per each OU to 25 different people. I am a total newbie in PS and just took a PS class recently. Below is what I have. I run the “Get-ADComputer” 25 times and then has a 25 Send email steps below (each to be sent to different people). This is way overkill. I’ve looked at the “For each object” command and try creating script for it but don’t know how i can have it loop and run each ou and then create 25 files to email each person.

THIS IS THE SCRIPT (I cut off all the repetitive lines) and sub some of generic names into the fields.

#
# Load the Microsoft Active Directory Module
Import-Module ActiveDirectory
#
#
#========================================================================================================================================================
#
# Get all Computers under different country OUs with blank description field and then list out name / descripton column.
#
#========================================================================================================================================================
#
Get-ADComputer -Filter 'Description -notlike "*"' -SearchBase "OU=1,OU=Z,DC=TEST,DC=local" -Properties description |
Select-Object name,description |
Out-File "C:\Test\OutFile\1ZComputers_No_Descriptions.txt"

Get-ADComputer -Filter 'Description -notlike "*"' -SearchBase "OU=2,OU=Z,OU=DC=TEST,DC=local" -Properties description |
Select-Object name,description |
Out-File "C:\Test\OutFile\2ZComputers_No_Descriptions.txt"

REPEAT 23 MORE TIMES

#==============================================================================
#
# Send Email with attachment of computers with no descriptions to site admins.
#
#==============================================================================
#
$SMTPServer = "x.x.x.x"
$SMTPPort = 587
$SMTPUsername = "test@test.com"
$Attachment = "C:\Test\OutFile\1ZComputers_No_Descriptions.txt"
$EncryptedPasswordFile = "C:\Test\MailRelayPswd.txt"
$SecureStringPassword = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$EmailCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SMTPUsername,$SecureStringPassword
$MailTo = "John Smith"
$MailFrom = "Me"
$MailSubject = "List of Computers with no description"
$MailBody = "Hi, attached is a list of computers with no description."
Send-MailMessage -From $MailFrom -To $MailTo -Subject $MailSubject -Body $MailBody -SmtpServer $SMTPServer -Port $SMTPPort -Credential $EmailCredential -Attachments $Attachment

#

#

$SMTPServer = "x.x.x.x"
$SMTPPort = 587
$SMTPUsername = "test@test.com"
$Attachment = "C:\Test\OutFile\2ZComputers_No_Descriptions.txt"
$EncryptedPasswordFile = "C:\Test\MailRelayPswd.txt"
$SecureStringPassword = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$EmailCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SMTPUsername,$SecureStringPassword
$MailTo = "John Doe"
$MailFrom = "Me"
$MailSubject = "List of Computers with no description"
$MailBody = "Hi, attached is a list of computers with no description."
Send-MailMessage -From $MailFrom -To $MailTo -Subject $MailSubject -Body $MailBody -SmtpServer $SMTPServer -Port $SMTPPort -Credential $EmailCredential -Attachments $Attachment

REPEAT EMAIL STEPS 23 MORE TIMES WITH DIFFERENT MAILTO

#THIS IS THE SCRIPT when I try using the ForEach -Object loop. It runs and then grabs all 25 different OUS and creates one txt #file but I want 25 different files so I can email the 25 different individuals

$ou = 'OU=1,OU=Z,DC=TEST,DC=local',
'OU=2,OU=Z,DC=TEST,DC=local',
#... (the other 23 OUs)

$ou | ForEach-Object {
Get-ADComputer -SearchBase $_ -Filter 'Description -notlike "*"' | Select-Object Name,Description
} | Out-File "c:\Test\Test.txt"

This just outputs everything into 1 file.

Move your pipe to Out-File inside the Foreach-Object loop and make the filename a variable so it can change each iteration.

Sorry, not sure how to make a filename with variable. I’ve added some more to the script. When it prompts for site name. Let’s say I enter USA then when I run the script it runs all 25 OU’s but just gives me one text file “USA_10-29_2020_nodescription.txt”. I need 25 different files. One UK_10-29_2020_nodescription.txt", one Paris_10-29_2020…etc. The “read-host” is probably useless here.

$date = Get-Date -format MM_dd_yyyy
$siteName = Read-Host “Enter the site name”
$csrName = $siteName + “_” + $date

$ou | ForEach-Object {
Get-ADComputer -SearchBase $_ -Filter ‘Description -notlike “*”’ | Select-Object Name,Description |
Out-File $("c:\Test" + $csrName + “_nodescription.txt”)
}

The filename needs to change each iteration. Simple way is to just number them like this:

$date = Get-Date -format MM_dd_yyyy
$siteName = Read-Host “Enter the site name”
$csrName = $siteName + “_” + $date
$x = 1
$ou | 
    ForEach-Object {
        Get-ADComputer -SearchBase $_ -Filter ‘Description -notlike “*”‘ | 
            Select-Object Name,Description |
                Out-File $(“c:\Test\” + $csrName + “_nodescription$x.txt”)
        $x++
}

 

I am getting this after I pasted your script but the below line is the same. Not sure what your “$x++” stands for.

Get-ADComputer : Error parsing query: ‘Description -notlike “*”’ Error Message: ‘syntax error’ at position: ‘22’.

$x++ increments $x by 1. It’s the same as $x = $x + 1 or $x += 1. Recommend reviewing assignment operators: about Assignment Operators - PowerShell | Microsoft Docs

I wasn’t even looking at your Get-ADComputer call, but based on the error you reported, I think your description argument is not correct. I’m not even sure what it is doing since * is a wildcard for anything so it read description is not like anything… I’m not sure what you are trying to filter but you might be able to remove the filter parameter. If not, take a look at this documentation for how to construct: about_ActiveDirectory_Filter | Microsoft Docs

 

Also please take a few moments to read the guide on posting code, and then update your post accordingly. Thanks!

Doug Maurer, is it possible to edit my 1st post? I can’t seem to find an option to edit it.

Sometimes when someone posts a long link it can push the edit button off the visible page. One of the moderators will need to adjust that first. Thanks for wanting to, though!

check your editor.

it looks like you have the Microsoft broken double quotes IE the Description -notlike “*”

vs Description -notlike “*”

easy to muck up, but the microsoft broken quotes aren’t actual doublequotes

David S, wow good eyes! I looked at it again and I still can’t tell the difference with those “*” they look the same to me.
However, I had a copy of the codes from a previous script so copied and paste it again and it ran and output me 25 files! I am half way there.

Now I need to send these 25 files to 25 different people.
Is there a way to run a similiar foreach loop instead of writing the send email strings 25 times?

Also, the 25 files output was defined with a varible by adding 1 so now the filenames are 10_30_2020_nodescription1.txt,
10_30_2020_nodescription 2.txt up to 25.txt. Is there anyway to set the variable so it can name according to country?
say 10_30_2020_nodescriptionUSA.txt, 10_30_2020_nodescriptionUK.txt, etc?

Just to be clear $OU contains a list of countries (as numbers) in your code right? If so, $_ or $PSItem will have the number inside the loop for the current country. If you want to convert that to text, you’ll have to build a hashtable or some other data structure to lookup the country name.

Mike R, correct the OU’s are all in different countries. I just changed it to number and letter to make it easier and shorter.

Ok, I’ll have to google $_, $PSItem, hastable, etc. You just lost me. Thanks! I do appreciate the guidance so at least I know what to look for.

ugh, now that i looked at my message, even more annoyed.

looks like its the forum software doing the converting from standard double quotes to the broken ones.

mental note when copying text from the forum to be on the lookout for.

Not when it’s formatted as code ^^

Is there a foreach loop for sending files to 25 different people or an easier way than scripting 25 times of the sendmail instances and substituting the MAILTO?

[quote quote=267800]Is there a foreach loop for sending files to 25 different people or an easier way than scripting 25 times of the sendmail instances and substituting the MAILTO?

[/quote]
Yes. Get-Help about_foreach

The online version of the documentation can be found here: about Foreach - PowerShell | Microsoft Docs

i.e.

# $people contains array of each person

foreach ($person in $people) {

#Put your code here and use $person to reference the current person in the loop.

}

 

What about the $attachment in the sendmail section. How do I change the $attachment to point to different files per email?

How do you know which person gets which attachment? If it’s hardcoded like John Doe gets OU - 1 and Jane Smith get’s OU -2 … then I would create a hashtable of that and iterate over the array of hashtables. Like this:

$admins = @(
@{name="Jon Doe"; OU=1},
@{name="Jane Smith"; OU=2}
#and so on
)

foreach ($person in $admins) {
    #reference current person with $person.name
    #reference OU for the current person with $person.ou
    #i.e. $attachment = "C:\Test\Outfile\{0}.txt" -f $person.ou
}

 

yeah it’s confusing as I would need to know who gets what file unless i line them up that John always get 1.txt, Jane gets 2.txt, etc.

If it possible to do a Read-host for the person’s email so if someone enters jsmith@test.com then ok run this function sendemail such that “jsmith” gets this email attachment.