• Status: Solved
  • Priority: Low
  • Security: Public
  • Views: 62
  • Last Modified:

Powershell script that searches network computers and sends back email

I need a Powershell script that will scan all computers on a network to find a file from a list of files and then send me an email telling me which computer has the file. I got this far

$computers = Get-ADComputer -filter *  | Select -Exp Name

$filenames = Get-Content "C:\filenamelist.txt"

foreach ($computer in $computers) {

foreach ($filename in $filenames) {
Get-ChildItem -Recurse -Force \\$computer\c$, \\$computer\d$ -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $false) -and  ( $_.Name -eq "$filename") } | Select-Object Name,Directory| Export-Csv C:\FoundFiles.csv -nti -append

___________________________________________________________________________________________________________________________________________
this will scan all computers on the network to finding files found from a file called filenamelist.txt. what i need help with is where to input the code for sending the email in order for it to only send an email if the file is actually found. If you could please test to see if my code works in the firstplace and then the email thing it would be much appreciated. Thanks to anyone who can help
0
Brady McDermott
Asked:
Brady McDermott
  • 2
1 Solution
 
footechCommented:
That code would be horribly slow, having to enumerate all files multiple times on each computer (once for each name in your list).
Not modifying your approach too much, this would be a little better.
$filenames = Get-Content "C:\filenamelist.txt"
$outfile = "C:\FoundFiles.csv"
Get-ADComputer -filter * | Select -Exp Name | ForEach-Object {
    $computer = $_
    Get-ChildItem -Recurse -Force \\$computer\c$, \\$computer\d$ -ErrorAction SilentlyContinue |
     Where-Object { ($_.PSIsContainer -eq $false) -and  ( $filenames -contains $_.Name ) } |
     Select-Object Name,Directory,@{n="Computer";e={$computer}}
} | Export-Csv $outfile -nti -append

If ( (Get-Item $outfile).Length -gt 0 )
{
    Send-MailMessage -To "a@example.com" -From "c@example.com" -Subject "found files" -Attachments $outfile -SmtpServer "smtp.example.com"
}

Open in new window


Making use of PS Remoting (fan-out) so that you don't have to process each machine in a serial fashion and all the drive data across the network would speed things up a lot.

Using the WMI class CIM_DataFile would be faster than Get-ChildItem.  An example of a function that makes use of it is at https://powershell.org/2013/01/29/find-files-with-wmi-and-powershell/
(I'll post it below).
Function Get-CIMFile {
#comment based help is here

[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="What is the name of the file?")]
[ValidateNotNullorEmpty()]
[alias("file")]
[string]$Name,
[ValidateNotNullorEmpty()]
[string]$Drive="C:",
[ValidateNotNullorEmpty()]
[string[]]$Computername=$env:computername,
[switch]$AsJob
)

<#
 strip off any trailing characters to drive parameter
 that might have been passed.
#>
If ($Drive.Length -gt 2) {
    $Drive=$Drive.Substring(0,2)
}

Write-Verbose "Searching for $Name on Drive $Drive on computer $Computername."

<#
Normally you might think to simply split the name on the . character. But
you might have a filename like myfile.v2.dll so that won't work. In a case
like this the extension would be everything after the last . and the filename
everything before.

So instead I'll use the substring method to "split" the filename string.
#>

#get the index of the last .
$index = $name.LastIndexOf(".")
#get the first part of the name
$filename=$Name.Substring(0,$index)
#get the last part of the name
$extension=$name.Substring($index+1)

$filter = "Filename='$filename' AND extension='$extension' AND Drive='$drive'"
Write-Verbose $filter

#get all instances of the file and write the WMI object to the pipeline
Get-WmiObject -Class CIM_Datafile -Filter $filter -ComputerName $Computername -Asjob:$AsJob
}

Open in new window


Some work would need to be done to adapt it to meet your exact needs.
1
 
footechCommented:
First code example shows a method for sending out the email only when a file is found (and includes improvements to the search).  Additional suggestions for improvement were also provided.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Improve Your Query Performance Tuning

In this FREE six-day email course, you'll learn from Janis Griffin, Database Performance Evangelist. She'll teach 12 steps that you can use to optimize your queries as much as possible and see measurable results in your work. Get started today!

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now