I've literally just C+P this code into my PowerShell, related to this question I asked on Super User.
It gives me exactly what I'm looking for but only for today's emails, can someone tell me how to add a a filter for emails the last two months for example? I looked through the code and I can't see anything related to data range so there might be another cmdlet that needs to be ran?
From a cursory glance at the script you linked, the individual emails appear to be iterated through in a foreach loop that uses the output of Get-MessageTrace as the collection of objects to iterate through. According to this documentation, Get-MessageTrace has a -StartDate and -EndDate parameter that you can specify a range of dates with.
So you just need to use those parameters to get a longer range of dates. Here's an untested example of what you'll probably need to do for the past two months:
Get-MessageTrace -StartDate (Get-Date).AddMonths(-2) -EndDate (Get-Date)
Edit: According to the parameter documentation, you may have to do some additional formatting after getting the date. I'm unfortunately not somewhere where I can test this, but here's what it says:
Use the short date format defined in the Regional Options settings for the computer on which the command is run. For example, if the computer is configured to use the short date format mm/dd/yyyy, enter 03/01/2010 to specify March 1, 2010. You can enter the date only, or you can enter the date and time of day. If you enter the date and time of day, you must enclose the argument in quotation marks ("), for example, "10/05/2010 5:00 PM".
This may not be necessary since you're already passing a DateTime object (the output of Get-Date) instead of a string... but worth mentioning, if you simply want to hard-code a string instead of getting the current time.
Related
I am working on a GUI-based Powershell tool to help users easily find out when their AD password is going to expire. Due to Covid restrictions, most users and not on-site and rely on VPN to connect to AD. A by-product of this is that many do not see the automatic pop-up in Windows to remind them of them to set a new password soon. Those that are on-site see the notification OK. It's a not a group-policy problem. The tool will be will be rolled-out in two different languages - one representing the 'mothership' (where is English is not normally spoken) and English for all other countries.
Some of the (mostly) Eastern European countries use a short date format that reads like 'd.M.yyyy.' - according to settings menu when one changes the 'Region' setting in Windows.
The tool calculates the difference between today and the expiry data and outputs the number of days to a text field. The actual expiry is display correctly in its own text field.
Some of the source code behind it all...
$thisUser = [Environment]::UserName
#make string
"net user " + $thisUser + " /domain"
#make cmd string
$fetch_net_user = "net user " + $thisUser + " /domain"
#execute command and store to variable
$net_user_data_array = Invoke-Expression $fetch_net_user
#Gets password expiry date (with header)
$password_expiry_with_header = $net_user_data_array[11]
#extracts only the date and assigns to new variable (the hours and minutes) can be ignored)
$password_expiry_as_string = $password_expiry_with_header.Split(' ')[-2]
# Home countries - works OK
try{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'dd.MM.yyyy', $null)
}
# Others - works OK
catch{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'dd/MM/yyyy', $null)
# where problem occurs
catch{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'd.M.yyyy.', $null)
}
finally{
#show GUI error window...
}
#fetch date... converted to yesterday to fix an off-by-one bug!
$today = Get-Date
$rightNow = $today.AddDays(-1)
#calc days left
$daysRemaining = (New-TimeSpan -Start $rightNow -End $password_expiry_as_dateTime).Day
# some other code follows, manipulating date values etc. Works with most date formats.
When executed the script will throw several errors.
The first is...
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
Others will follow such as
You cannot call a method on a null-valued expression.
As the difference between today and the expiry date cannot be calulated.
Is there any easy fix for this? I'd rather avoid having to write a long list of 'if' statments for each country/culture. Thanks!
I'm sure the code could be a little bit more elegant, and that will be addressed in a later version. Right now, getting it to work some of the more obscure date formats is my priority.
Something else that I should stress is that this tool works in a 'read only' capacity. No 'Set-Item' commands are used.
Regards,
WL
You have 2 problems:
Multiple date formats used interchangeably
Trailing dots on some strings
The first problem can be solved by passing multiple format strings to ParseExact() - it'll try each in order until it successfully parses the input string (or reaches the end of the list):
[datetime]::ParseExact($password_expiry_as_string, [string[]]#('dd.MM.yyyy', 'dd/MM/yyyy', 'dd.M.yyyy', 'd.M.yyyy'), $null, [System.Globalization.DateTimeStyles]::None)
The second problem can be solved by trimming trailing dots:
[datetime]::ParseExact($password_expiry_as_string.TrimEnd('.'), [string[]]#('dd.MM.yyyy', 'dd/MM/yyyy', 'dd.M.yyyy', 'd.M.yyyy'), $null, [System.Globalization.DateTimeStyles]::None)
I have a PowerShell script that I am using to download a file from a URL every morning, however it has started putting the date on it every day, therefore making it imppossible to use a scheduled PowerShell everyday to download it.
Is there anyway to use a wildcard to make it pick up all of the dates?
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile("https://test.com/store/scheduled/320%2019.10.22.csv","\\server\shared\Reports\RawData\Cross Selling Data.csv")
The bold bit is what I am looking to Wildcard after '320' as this is the report number but before .csv. I've tried * but that doesn't seem to work. The date obviously changes on each day's report.
When it comes to using wildcard, the answer is no. It's impossible to use wildcard while making web requests as it'd require checking every possible path.
What is possible is to construct the path programmatically if you know the pattern. For example, in your case
# That input
PS> Get-Date -Format 'yy.MM.dd'
# Gives you the following result
19.10.22
which looks similarly to the pattern you included in your code (I assume %20 is space). To use it in string (assuming you use double quotes ") you can use the following:
"https://test.com/store/scheduled/320%20$(Get-Date -Format 'yy.MM.dd').csv"
Last, but not least, as #Tomalak mentioned in comments, Invoke-WebRequest might work for you as well.
I have this PowerShell snippet to delete e-mail between 2 dates:
Search-Mailbox -Identity <username> -SearchQuery '(Received:09/20/2012..10/12/2012)' -deletecontent
I want to make it dynamic so that it deletes e-mail older than 6 months. How can I calculate the date of 6 months ago to use in this snippet?
I have tried:
$date = (Get-Date).AddMonths(-6)
Search-Mailbox -Identity Sales -SearchQuery '(Received:<$date)' -DeleteContent
but it shows the error message:
The property keyword isn't supported.
$date is a System.DateTime object. When converted to a string it will show both date and time information which is dependent on your regional settings. This is what mine looks like:
PS M:\Scripts> $date = (Get-Date).AddMonths(-6)
PS M:\Scripts> $date
Sunday, March 27, 2016 9:30:20 AM
PS M:\Scripts> "$date"
03/27/2016 09:30:20
That last line does not meet the standards required by KQL (Keyword Query Language)
YYYY-MM-DD
YYYY-MM-DDThh:mm:ss
YYYY-MM-DDThh:mm:ssZ
YYYY-MM-DDThh:mm:ssfrZ
Since you just want the date portion lets just get that.
(Get-Date).AddMonths(-6).ToShortDateString()
3/27/2016
While that does not use hyphens, in my case, it appears the syntax allows for it in your test cases. There are oodles of ways to format dates in PowerShell. Here is one that conforms to the syntax in TechNet
(Get-Date).AddMonths(-6).ToString("yyyy-MM-dd")
2016-03-27
Point is you have to do something that will satisfy your query syntax. Test some string without -deletecontent first or just write the string to console to see what it looks like.
For a span of time you would use one of the above suggestions and, assuming you save those string results in variables, it would look something like this:
-SearchQuery '(Received:$fromDate..$toDate)'
I am working with powershell that retrieves timesheet information from a biometric device. One of the search arguments used to query the timesheet is the date and time. Currently, I retrieve the date and time in the local machine where my powershell is installed. My code inside my powershell script for getting the date is:
get-date -format yyyy-MM-dd
However, if someone changes the date and time of the computer, my query gets affected. Is there a way to retrieve the current datestamp for Asia/Manila using powershell? I dont want to use local machine time anymore.
You can convert the date to universal time before formatting it as a string:
(Get-Date).ToUniversalTime().ToString('yyyy-MM-dd')
With the script from https://gallery.technet.microsoft.com/scriptcenter/Get-Network-NTP-Time-with-07b216ca you can get the time from a ntp server.
download the tool and start it like that:
.\Get-NtpTime -Server asia.pool.ntp.org | Format-List *
You can find other ntp pools oh this site http://www.pool.ntp.org/de/
We have a batch file that runs an end-of-month process. Right now it's a manual process, but we'd like to automate it based on when EOM falls. If the last work day of the month is a Friday (or other weekday), we run the script on Friday night or Saturday. If it falls on a Saturday or Sunday, the script is run on Monday following the weekend. There may be a few exceptions, but that's the general idea.
We're having trouble figuring out how to automate this based on date. Any options will be considered. Powershell, batch, etc...
Any help would be greatly appreciated.
Edit - The dates it selects to run can be a bit random. If we could have it read in a text file with a list of dates to run that would work too.
So we could have a list of dates like:
04-30-2015,
05-31-2015,
06-29-2015,
Then a script could be run that says if today is equal to any of these dates, run the batch file.
The logic isn't completely clear to me, but as said in the comment above, you could run a PowerShell script using Windows Task Scheduler every day (or only Friday/Monday?) and have that script check if the time is right to do something.
From what I can tell it either has to run on Friday or Monday.
You can get the current date in PowerShell with the Get-Date command.
If you pass this through Get-Member you can see all the methods you have on the date object to figure out if the time is right to do something.
get-date | get-member
You'll probably need some methods or properties like this to implement the check:
$today = get-date
$today.DayOfWeek # prints e.g. "Monday"
$today.DayOfWeek -eq 1 # Returns True on Monday
$today.AddDays(1) # Next day, the number can be negative or positive
$today.Day # Returns 6 right now (april 6th)
There are plenty of resources that discuss calling a PowerShell script in Task Scheduler. If what you currently do is run a batch then configure your task to run at 5:00pm every day checking the date against all the dates in your text file.
$milestones = Get-Content c:\temp\dates.txt
$today = Get-Date -Format "MM-dd-yyyy"
If($milestones -contains $today){
# Do stuff and things.
# cmd.exe /K C:\Path\To\Batch.bat
}
If there was a line in the text file "c:\temp\dates.txt" for "04-06-2015" that would satisfy the If condition. Then you could uncomment the line with cmd and update as required.
If you have issues with these concepts it is expected that you do a little research before you ask. If you are still stuck after that please either edit your question of ask a new question.