Count files in Home and send mail - Powershell - powershell

I'm not Powershell guru but do anyone of you have some script which counting files in an folder and automaticlly send mail to user? Our users have an roaming profile
(\\profile-srv\%username%)
Folder name is the same as username. Is it possible to have an script which will count files in every home folder and send email to user?
domain is: FirmaBis.org total users: 150
So count in ex. aaba and send mail to aaba#firmabis.org
Count next aaca and send mail to aaca#firmabis.org
So script will count files and send mail to user based on folder name and + firmabis.org.
Thanks!

# Get just the directories in the user directory share, ignore any files, loop over them
Get-ChildItem -Path '\\server\share' -Directory | ForEach-Object {
# List all the files in the current folder (loop variable $_ is the folder)
$FilesInFolder = #($_ | Get-ChildItem -Recurse -Force -File)
# Count the files
$NumFiles = $FilesInFolder.Count
# Calculate how many MB they take up, and show it to 2 decimal places
$FileSize = $FilesInFolder.Length | Measure-Object -Sum | Select-ExpandProperty Sum
$FileSize = "{0:.0}MB" -f ($FileSize/1MB)
# Build the email message
$Message = #"
Hi,
The folder for account ($($_.Name)) has $($FilesInFolder.Count) files in it.
They add up to $FileSize
"#
# Send the message through an SMTP server which is configured to allow
# unauthenticated relay emails from the computer running the script.
Send-MailMessage -SmtpServer yourmailserver -To "$($_.Name)#FirmaBis.org" -From 'script#FirmaBis.org' -Body $Message
}
Untested, but ...

I have not seen anything that you have tried so far. Just to give you a set off:
You can get the list of Files count using the combination of Get-childitem and .Count method.
( Get-ChildItem D:\FolderName | measure-object).Count
You can store the output in the variable.
Then, You can pass the variable as a BODY in Send-MailMessage with which you can send emails.

Related

How do I automate my PowerShell script to read in the clients ID's and their emails - instead of how I have done by having to manually add them?

I have done a PowerShell script where I want to email all the client on the server about their housekeep. I have a document attached for them to read through.
Currently I have it so I have to write in the clients mnemonic and then their email. I want it to be automated -- like have the clients mnemonic and email address stored in a txt folder or excel spread sheet. Have the script read in the details from there?
This is currently what I have.
$FLMDIR = 'E:\FLM_Mailer
Copy-Item E:\FLM_Mailer\E_MSGFILE.TXT -Destination $FLMDIR\msgfile.txt
$MSG_FILE = 'E:\FLM_Mailer\msgfile.txt'
$ClientID = Read-Host -Prompt 'Enter ClientID'
$EmailAddr = Read-Host -Prompt 'Enter Client Email Address'
# Search and Replace clientID
(Get-Content $MSG_FILE) | Foreach-Object {$_ -replace "AAA","$ClientID"} | Out-File $MSG_FILE
E:\FLM_Mailer\FTRMail.exe $MSG_FILE -to $EmailAddr -f myemail#email.com.au -server 10.10.10.311 -s "Repository Housekeeping in folder/ifolder system" -attach "$FLMDIR\folder Housekeeping for Hosted Clients.docx" -log E:\FLM_Mailer\FLMmail_log.txt -debug
#Remove-Item $FLMDIR\msgfile.txt

powershell automatic data creation time watch

i have a windows server with some hotfolders, all data in the folders will be transfered in a other directory. But sometimes the data stucks in the same folder and the service is still running.
Because of that i wanted to created a powershell script that watch the data creation time and compare it with the actual time. If the difference is more then 10 min send Mail to me, that i can restart the service.
The script should do loop if he detect a data that isnĀ“t transferred and send only one mail and not a mail for every data.
I tryed it for myself and stuck at this point:
Get-ChildItem -Force C:\Ueberwachung
Where-Object{($_.LastWriteTime -le $CurDate.AddMinutes(-10))}
$PSEmailServer = "192.168.0.11"
ForEach ($file in $Files) {Send-MailMessage -to "luis.jablonski#boyn.eu" -from "PowerShell
<ps#boyn.eu>" -Subject "Hotfolder Alarm" -body "Dateien werden nicht bearbeitet"
break
}
the script detectet all datas in the folder see:
Verzeichnis: C:\Ueberwachung
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 30.04.2021 09:39 0 asdsad.pptx
-a---- 30.04.2021 09:39 0 sadsada.docx
-a---- 30.04.2021 09:39 0 sadsadsadsad.txt
-a---- 28.04.2021 16:03 0 test.txt
but doesnt send me a mail, so i think something like my trigger or the compare with the actual time doenst work.
Has anybody a Idea what my Problem ist?
Im glad for every help
Dear Luis
Your script is behaving as I would expect.
Get-ChildItem is output to screen as it is not placed into a list ($Files).
$Files is empty so the loop is never 'looped'.
Issues here:
In the line: ForEach ($file in $Files) {Send-MailMessage... You
have not added anything to $Files. You could pipe Get-ChildItem -Force C:\Ueberwachung Where-Object{($_.LastWriteTime -le $CurDate.AddMinutes(-10))} to $Files to give the list some data.
Other wise $Files is empty so there's nothing to loop through and
therefore, no emails.
As mentioned, Send-MailMessage needs the param -smtpserver $PSEmailServer added, so it knows via which SMTP server to send the
emails.
Last but not least, do you really want an email per file in $Files?
Perhaps you want to change the code so that the list of $Files is in
the email body as a whole?
Not quite sure why break is in there?

powershell-open .msg attachment without saving

I need to write a powershell script that will go through an Outlook folder, pull out a uid from a URL in the email and send a GET with the uid in a new URL.
This is fine for emails that are just forwarded to the mailbox, but sometimes these are forwarded as attachments. I would like to open the .msg file to pull out the uid in the same way, but I can't find a way to do it without saving the file down first.
My initial idea was to save the file, open it, pull out the information, then delete the .msg. The problem is that Outlook keeps the instance of the .msg file open, so it cannot be deleted. I could do an $outlook.quit(), but then it will close the instance of Outlook that I'm using to go through the rest of the emails.
I'd prefer to not have to save every single .msg individually in a file and then interate through all of them if possible.
Is it possible to just read the body of the .msg file as if it's just another email message?
Here is my code:
# Mailbox name
$mailbox = "abuse#place.com"
# Name of folder containing reported phishing emails
$folderName = "SelfPhishTest"
# Create the Outlook object to access mailboxes
$Outlook = New-Object -ComObject Outlook.Application;
# Grab the folder containing the emails from the phishing exercise
$Folder = $Outlook.Session.Folders($mailbox).Folders.Item($folderName)
# Grab the emails in the folder
$Emails = $Folder.Items
# Path to save attachments to
$filepath = "C:\SavedPhishEmails\"
# Run through each email in the folder
foreach($email in $Emails){
# Output Sender Name for Testing
Write-Host $email.SenderName
# The number of email attachments
$intCount = $email.Attachments.Count
# If the email has attachments, let's open the .msg email
if($intCount -gt 0) {
# Let's go through those attachments
for($i=1; $i -le $intCount; $i++) {
# The attachment being looked at
$attachment = $email.Attachments.Item($i)
# If this is a .msg, let's open it
if($attachment.FileName -like "*.msg"){
$attachmentPath = $filepath+$attachment.FileName
$attachment.SaveAsFile($attachmentPath)
Get-ChildItem $attachmentPath |
ForEach-Object {
$msg = $Outlook.Session.OpenSharedItem($_.FullName)
$msg.Body
}
Remove-Item $attachmentPath
}
}
}
}
Figured it out.
Adding this will release the .msg file
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($msg) | Out-Null

Exporting array results to csv using powershell

I'm working on a powershell script utilizing the Citrix XenApp sdk. What I am trying to do is get the following values using one of the citrix cmdlets; Load, User count, and Server count (which uses another cmdlet) and export to csv.
I created a csv file that contains the name of the delivery groups I want to query, so I import that csv and start my array by calling a couple of the citrix cmdlets:
# Add Citrix XenApp sdk
Add-PSSnapin Citrix.*.Admin.V*
# Define Dashboard Server Name as well as import the Delivery Group csv file.
$DashboardServer = "server.name"
$delivery_group_csv = Import-Csv \\$DashboardServer\path_to_file\file.csv -Delimiter ","
# extract citrix loads per delivery group as well as Session counts for each delivery group
foreach($silo in $delivery_group_csv) {
$DeliveryGroupName = $silo.DeliveryGroupName
$LoadIndex = Get-BrokerMachine -DesktopGroupName $DeliveryGroupName
$SiloLoad = ($LoadIndex | Measure-Object 'LoadIndex' -Sum).Sum/1000
$UserCount = ($LoadIndex | Measure-Object 'SessionCount' -Sum).Sum
$ServerCount = Get-BrokerDesktopGroup -Name $DeliveryGroupName
$DG_servercount = ($ServerCount).TotalDesktops
Write-Host $DeliveryGroupName "- Load" $SiloLoad"%" " - Servercount" $DG_servercount "- " Total Users" - " $UserCount | Export-Csv -Path \\$DashboardServer\path_to_save\new_file.csv -Append -Encoding UTF8 -NoTypeInformation
The problem is when it gets exported to csv I only get a blank csv file. I am fairly new to powershell and have tried a variety of things, but completely at a loss to get this to work. Any help would be greatly appreciated.

Looking for advice on how to proceed with working powershell script

So I posted for and got some help with this script:
#Command to get list of folders with logfiles where the logfile is at least 30 minutes old send results to variable.
$varlogfile = Get-ChildItem -Path "drive:\folder" -Recurse -Include "logfile" | Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))}
#Add a carriage return to results contained in the variable so email is easier to read
$varlogfile = $varlogfile -join "`r`n"
#Email setup from this line down to next comment
$SMTPServer = "email.server"
$From = "Administrator <administrator#place.com>"
$To = "email","email2"
$Subject = "A Logfile older than 30 minutes has been detected"
$Body = "Logfile(s) older than 30 minutes have been detected in the following folder(s):
$varlogfile
Please login and attempt to process the files manually, if the manual process fails, open a ticket with someone.
From the Admin
"
#Email setup above this line
#If statement that looks for the text blah in the variable, if found email is sent.
if($varlogfile -match "blah")
{
#Command to send email
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer
}
exit 0;
And all that is working perfectly.
Here's the thing though. Over the weekend sometimes we may get a stuck logfile that can't be resolved until Monday morning and it would be nice to be able to turn off alerts when this happens.
Now I'm very new to powershell and this script has been my learning experience. The way I see it is I have 3 choices:
Keep the get-childitem from returning a result if it sees logfile and logfile.stop.
After get-childitem has produced $varlogfile, search $varlogfile for logfile.stop and delete the lines logfile and logfile.stop from it.
Rewrite the whole thing from scratch and produce $varlogfile in a better way that makes it easier to work with the results.
Thoughts and opinions? I'm leaning toward method 2, as I think I can figure that out, but I'm curious if that is a way of pain. I'd really like your input on this.
Thanks people!
I think you're on the right path with your current plan, so I'll help you with approach #2, creating a .sent file when we send an email, to keep the emails from sending multiple times.
Our first step: When an e-mail is sent , we create a new file titles $logfile.MessageSent or something like that. Doing this allows an e-mail to be sent, and for us to also create a flag that we can search for later in the filesystem to determine whether or not we send another e-mail.
#If statement that looks for the text blah in the variable, if found email is sent.
if($varlogfile -match "blah")
{
#Command to send email
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer
New-Item -path $varLogfile.Sent -itemType File
}
Our second step: Modify our Get-ChildItem query to search for the flag:
$varlogfile = Get-ChildItem -Path "drive:\folder" -Recurse -Include "logfile" |
Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))} |
? "($_.BaseName).sent" -notin (Get-ChildItem -Recurse -Include "*.sent" -Path "drive:\folder" | Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))})
This second modification to the $varlogfile step is hard to understand, admittedly. Here is how I've changed it:
Get a lit of files in the drive\folder path, recursively and include logfile
Where the LastWriteTime is older than 30 mins
Where filename.sent is not found in the same directory
The only other thing you'll need to do is add a cleanup task to regularly delete the .sent files, and you're good to go.
Please let me know if you have any questions about this approach, as I want to be sure you understand and to help you learn.