I have a basic PowerShell (v4) script running on Server 2012. I decided to have Task Scheduler task it. Task scheduler instance is running as domain and machine administrator, Runs whether the user is logged on or not and runs with Highest Privileges. It's configured for Windows Server 2012 R2.
It starts a program of "Powershell" and this is my argument: "-ExecutionPolicy Bypass -file F:\AdMgmt\scripts\newcheckandcopy.ps1"
The problem: It executes some of the script just fine - however, I have an "If/Else" statement that it ignores. I've tried this with two scripts now and the Task scheduler always executes fine, but doesn't handle the If/Else stuff - it just skips over it and runs everything else.
This is the text of the script (it runs perfectly from the powershell console when logged in as the same account that runs the task):
$path = 'Q:\'
$stats = 0
$msg = ''
$days = 1
$hours = 0
$mins = 0
$logtime = Get-Date -uFormat "%y%m%d%H%M"
$files = #(Get-ChildItem -Recurse -Path $path -Include '*.*' | ?{ $_.LastWriteTime -lt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$minutes) -and $_.psIsContainer -eq $false})
if ($files -ne $null) {
$f_names = [System.String]::Join('|',$files)
$msg = 'Message: ' + $f_names
$stats = $files.Count
Send-MailMessage -to "domain#test.com" -from "domain#test.com" -subject "FileMaker Files older than 1 Day" -body $msg -smtpserver "smtp-relay.test.com"
} else {
$msg = 'Message: 0 files exceed defined age'
Send-MailMessage -to "domain#test.com" -from "domain#test.com" -subject "FileMaker Files OK" -body $msg -smtpserver "smtp-relay.test.com"
}
Copy-Item Q:\* F:\admgmt\ -recurse
Add-Content f:\admgmt\logs\checkandcopy.txt $logtime
Write-Host $msg
Write-Host "Statistic: $stats"
I'm guessing your issue is you are running the script outside of user context. the Q:\ drive would not be available to it. PowerShell supports UNC paths so you might be able to substitute the actual path that Q:\ points to.
Related
I am trying to download the Total counts by date for all King County excel file using a script that will be run later on using task manager. I am stuck due to the link not being static and its naming convention will most likely change in the next few months.
Here's the code that I've written so far:
#echo off
::Script to download COVID-19 Data
echo "Downloading Total counts by date for all King County"
powershell -Command "Invoke-WebRequest https://www.kingcounty.gov/depts/health/covid-19/data/~/media/depts/health/communicable-diseases/documents/C19/data/covid-data-daily-counts-sept-14.ashx -Outfile CovidData.xlsx
echo "Download has been successful!"
cls
pause
I was wondering if there's a way to add a wild card like "*" in the invoke-webrequest to ignore the "sept-14" part of the link.
Link: https://www.kingcounty.gov/depts/health/covid-19/data/daily-summary.aspx
Link that needs a script to auto download with task manager (Total counts by date for all King County): https://www.kingcounty.gov/depts/health/covid-19/data/~/media/depts/health/communicable-diseases/documents/C19/data/covid-data-daily-counts-sept-14.ashx
I created and tested Powershell Script on my side with Windows Powershell ISE and it works 5/5, hope that will work too for you !
$start_time = Get-Date
$url = "https://www.kingcounty.gov/depts/health/covid-19/data/daily-summary.aspx"
$xlFile = "E:\Test\CovidData.xlsx"
$http_request = New-Object -ComObject Microsoft.XMLHTTP
$http_request.open('GET', $url, $false)
#Sending the request
$http_request.send()
$Contents = $http_request.ResponseText
$pattern = "([\w\-\.,#?^=%&/~\+#]*[\w\-\#?^=%&/~\+#])(\.ashx)"
$Links = $Contents | Select-String $pattern -AllMatches | ForEach-Object {$_.Matches.Value} | sort -unique
$Filter = $Links -match "data-daily"
$MyUrlFile = "https://www.kingcounty.gov/depts/health/covid-19/data/" + $Filter
$MyUrlFile
Invoke-WebRequest "$MyUrlFile" -Outfile $xlFile
if (Test-Path $xlFile) { Start $xlFile }
Write-Output "Running Script Time taken is : $((Get-Date).Subtract($start_time).Seconds) second(s)"
I'm trying to get a script to work but I'm running into some issues. We have a folder that gets ZIP files sent to it via FTP and a service on the server moves them to another directory for processing. The issue is sometimes the service will be running but not doing anything so the monitoring doesn't sent a alert. I am working on a PowerShell script to check the folder for .zip files older than 30 minutes and if found send a email to that team to check out why the files haven't been moved. Below is what I have written so far, any help would be greatly appreciated. Thanks.
$Path = "c:\test"
$SMTPServer = "mail.server.com"
$From = "Monitor Prod <mon.server.com>"
$To = "people#server.com"
$Subject = "Alert: Potential issue with service in PROD"
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject"
Smtpserver = $SMTPServer
}
$File = Get-ChildItem -path $path -Filter ".txt" | Where-Object {$_.LastWriteTime -lt (Get-Date).AddMinutes(-30)}
If ($File)
{ $SMTPBody = "Batches older than 30 minutes located in c:\test while service is actively running. Service may require a restart."
$File | ForEach { $SMTPBody += "$($_.FullName)`n" }
Send-MailMessage #SMTPMessage -Body $SMTPBody
}
I really stink at scripting and I need your help. I pieced together this script from several places on the internet and it works, until I enable my IF statement...
I'm just trying to get a count of files of a folder from a UNC path, and if it's over a specified amount, then I want it to send an email letting me know with the current count.
However, if I uncomment the if ($count -gt 50) part, then I won't get an email if the count is over 50.
I don't know how to make the ".Count" a variable for me to use elsewhere in the script. Can someone please help?
Then I'll need to figure out how to run it. Was thinking just a scheduled task in windows and have it run every few minutes or something, but if you have any better ideas, I'd like to hear them!
$FolderList = #(
"\\server\path\test"
)
$Body = ($FolderList | ForEach-Object {
"Check to see if Sweep Service is running, file count for '$($_)': " + (Get-ChildItem -Path $_ -File -ErrorAction SilentlyContinue | Measure-Object).Count
}) -join "`r`n"
#if ($count -gt 50)
#{
$From = "me#you.com"
$To = "me#you.com"
$Subject = "Sweep Checker"
$SmtpServer = "webmail.you.com"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SmtpServer
#}
your major problem seems to be NOT saving the file count to any variable. instead, you are saving the value as part of a string - not a number. [grin]
the following code explicitly puts the file count for the current dir into a var, adds that to the total count, and then uses the current count to build your output string for the body of your msg.
$FolderList = #(
$env:TEMP
$env:USERPROFILE
$env:ALLUSERSPROFILE
)
$TriggerFileCount = 20
$TotalFileCount = 0
$Body = foreach ($FL_Item in $FolderList)
{
$CurrentFileCount = #(Get-ChildItem -LiteralPath $FL_Item -File -ErrorAction SilentlyContinue).Count
$TotalFileCount += $CurrentFileCount
# send out to the "$Body" collection
'Check to see if Sweep Service is running, file count for [ {0} ] = {1}' -f $FL_Item, $CurrentFileCount
}
if ($TotalFileCount -gt $TriggerFileCount)
{
$SMM_Params = #{
From = 'NotMe#example.com'
To = 'NotYou#example.com'
Subject = 'Sweep Checker'
Body = $Body -join [System.Environment]::NewLine
SmtpServer = $SmtpServer
}
$SMM_Params
#Send-MailMessage #SMM_Params
}
output ...
Name Value
---- -----
Subject Sweep Checker
From NotMe#example.com
To NotYou#example.com
SmtpServer webmail.you.com
Body Check to see if Sweep Service is running, file count for [ C:\Temp ] = 22...
the full content of the $Body variable ...
Check to see if Sweep Service is running, file count for [ C:\Temp ] = 22
Check to see if Sweep Service is running, file count for [ C:\Users\MyUserName ] = 5
Check to see if Sweep Service is running, file count for [ C:\ProgramData ] = 0
I need to find new files in a folder which are over 10 MB in size, and then send a mail with the name of the files.
The tricky part: Mail should be send when there is a new file arrives in the folder, so I have to always keep track and differentiate between the old file and new file.
Problem: I have written the following code and am not able to build the logic for mail. How can I identify the new file comes and trigger the mail?
$namearray = #()
$n = gci 'C:\Users\RF\local\ReuseLibrary\FamilySaveDirectory' | % {get-item $.FullName| ? { $.length -gt 10mb }}
foreach($a in $n) {
$namearray += $a.name
}
$namearray
Send-MailMessage -To *#gmail.com -From '****#*.com' -Subject "Add User for $namearray NX License" -Body "Script execute $namearray successfully.." -SmtpServer 'mail.****.de'
As already pointed out in the comments, you can use the FileSystemWatcher object to monitor your filesystem. It got a little more tricky than just using the object, because you also need to be able to get the files which are already in the folder, not only the newly created ones.
Should the script really trigger the mail every time it has a new item in the $namearray? Maybe you'll get a flood of e-mails then.
It's better to use a function instead of a script to do your task because you have more flexibility, so you can check for only newly created files, and also for all files inside your folder.
Please try the function. I couldn't test it very well, because I don't have a folder where 10 MB large files get created all the time.
Usage:
To get all files (the wildcard * in the filter is important!):
Get-Files -filter '*.txt' -folder 'C:\yourfolder' -AllFiles
To monitor only new created files:
Get-Files -filter '*.txt' -folder 'C:\yourfolder' -NewFiles
Function:
Please edit the Send-MailMessage part so that you will receive the mail on your account.
function Get-Files() {
param(
[string]$filter,
[string]$folder,
[Parameter(ParameterSetName='AllFiles')]
[switch]$AllFiles,
[Parameter(ParameterSetName='NewFiles')]
[switch]$NewFiles
)
# Preparing the Name array
[string[]]$namearray = #()
if(!$NewFiles.IsPresent) {
# Getting all files which are already inside the
# folder and more than 10 MB
$files = gci $folder | % { get-item $_.FullName |
? { $_.length -gt 10mb -and $_.Extension -like $filter} } |
% { $namearray += $_.FullName }
# Send E-Mail
$secondnamearray = $namearray | out-string
Send-MailMessage -To '*#gmail.com' -From '****#*.com' -Subject "Add User for NameArray NX License" -Body $secondnamearray -SmtpServer 'mail.****.de'
$namearray = ""
}
# Monitoring of the Files
$monitoring = New-Object System.IO.FileSystemWatcher
$monitoring.Filter = $filter
$monitoring.path = $folder
$monitoring.EnableRaisingEvents = $true
$event = Register-ObjectEvent -InputObject $monitoring -EventName Created -Action {
# Checking for filesize
$x = (get-item $eventArgs.FullPath).length / 10mb
if ($x -ge 1) {
Write-Host "New Item found: $($eventArgs.FullPath). Sending E-Mail!"
$namearray += $eventArgs.FullPath
$newnamearray = $namearray | out-string
Send-MailMessage -To '*#gmail.com' -From '****#*.com' -Subject "Add User for NameArray NX License" -Body $newnamearray -SmtpServer 'mail.****.de'
$namearray = ""
}
}
}
I'm studying for Network\System Admin certification (MCSE is in it) and among other things we started to delve into powershell scripting.
At any rate my instructor gave me a challenge to do as follows:
I need to create a PS script which will run Robocopy tool in order to mirror a folder from point A to Point B and that script should run as a schedule task (/w Task Scheduler).
If robocopy have encountered any errors the script should send a mail via the Company's exchange mail server to the Admin in charge of the process.
I'm not Scripting savvy of any sort so I had to sit and learn the syntax, command etc before I could start working.
Here is what I got so far:
# PowerShell Robocopy Script V.1 | Liron Ben-David
# Variables
$Source ="C:\Source\"
$Destination = "C:\Destination\"
$ExitCode = "Null"
#Copying Process
Robocopy $Source $destination *.* /mir /r:100 /w:10
# Return Code Section
if ($LASTEXITCODE -eq 0) {$ExitCode = "Succeeded, Code: $LASTEXITCODE" }
elseif (($LASTEXITCODE -gt 1) -and ($LASTEXITCODE -lt 17)) {$ExitCode = "Failure, Code: $LASTEXITCODE" }
else {$ExitCode = "No Return Code"}
Write-Host $ExitCode
## Failure Report
if ($ExitCode -gt 1) {Send-MailMessage -to "Admin (Admin#Domain.com)" -From "Machine-Robocopy1 (M1RC#domain.com)" -Subject $ExitCode -SmtpServer mail.domain.com}
else {exit}
basically if there is any kind of error in the process the script supposed to send an email with the script error code as the "Subject" of the message.
First of all:
Does this script contain any embarassing mistakes I did and which I should avoid in the future?
Secondarily:
I never used the CLI to send email messages, using the Send-Mail CMDLET I should have used a credentials switch but according to what I've read\watched it seems it will pop up a window for input.
Considering I'm setting this script for a Domain Environment wouldn't the SSO feature will kick in when I try to send the message?
EDIT:
Also noticed I mixed the error codes so I need to re-calibrate the error code lines.
EDIT 2: Version 2 bsaed on your help,
# PowerShell Robocopy Script V.2 | Liron Ben-David
# Variables
$Source = "C:\Source\"
$Destination = "C:\Destination\"
$ExitCode = "Null"
$ReturnCodeValue = "Void"
$Log = "C:\RoboLogs\RobocopyLog.txt"
#Copying Process
Robocopy $Source $destination *.* /mir /r:100 /w:10 /UniLog:C:\RoboLogs\RobocopyLog.txt /v
# Return Code Section
if (($LASTEXITCODE -eq 0) -or ($LASTEXITCODE -eq 1) -or ($LASTEXITCODE -eq 3) -or ($LASTEXITCODE -eq 5) -or ($LASTEXITCODE -eq 6) -or ($LASTEXITCODE -eq 7)) {$ExitCode = "Succeeded, Code: $LASTEXITCODE" }
elseif (($LASTEXITCODE -eq 2) -or ($LASTEXITCODE -eq 4)) {$ExitCode = "Error, Code: $LASTEXITCODE" }
elseif ($LASTEXITCODE -gt 7) {$ExitCode = "Failure, Code: $LASTEXITCODE" }
else {$ExitCode = "No Return Code"}
$ReturnCodeValue = $LASTEXITCODE
# Debug Section
#Write-Host "Did the script completed succesfuly:" $?
#Write-Host "Script Exit Code:" $ExitCode
#Start-Sleep -s 4
## Failure Report
if (($ReturnCodeValue -gt 7) -or ($ReturnCodeValue -eq 2) -or ($ReturnCodeValue -eq 4)) {Send-MailMessage -to "Admin (Admin#Domain.com)" -From "Machine-Robocopy1 (M1RC#domain.com)" -Subject $ExitCode -SmtpServer mail.domain.com –Attachments $Log -UseSsl}
else {exit}