I'm passing a string that represents a date i.e. 20180625 to my Powershell script.
I'm then taking the string parameter, which is called $currentDate and formatting it as follows:
$date = [datetime]::ParseExact($currentDate,"yyyyMMdd",$null)
However, when I write the $date variable out it's displaying as 6/29/2018 12:00:00 AM.
I'm doing this because I need to get the day of the year for my script:
$dayofyear = ($date).dayofyear
Which works. I just expected the $date to be in the yyyyMMdd format. Just curious as to why this is happening.
The format parameter for ParseExact tells the parser what format the date you are giving it is in. The object you get back is a DateTime object not a string. To get the string in the format that you want, use the .ToString() method then give if the format that you want the string to be in.
As an example:
$currentDate = '20180629'
$date = [datetime]::ParseExact($currentDate,"yyyyMMdd",$null)
$dayOfYear = $date.DayOfYear
$date.ToString('yyyyMMdd')
$date is an object of type [datetime] which contains an exact measure of time in ticks. For instance, a timespan of 1 day would be 864000000000 ticks. Thus it is not possible to have $null values in a lesser field (864 ticks would only be a few milliseconds). $date prints to the console with a default formatting, which can be changed. However, since each field down to -Milliseconds is populated as 0, when that default format does contain fields such as -hours, they will be displayed as the minimum value (in this case, 12am exactly).
Related
I'm trying to take output from Date-Time in Powershell and change it into an integer (rather than a date-time object or a string) so I can subtract it from another date later.
I have two variables:
$nowBase = Get-Date
and
$loopTime = Get-Date # which will be used later for the aforementioned math.
Thank you for any help.
so I've got a CSV file with 5 headings: name, collectionDate, location, equipmentNotes, manager.
Now my collectionDates are all in UK format so DD/MM/YYYY. I only want to import data from the CSV with collection dates that are 7 days or less in the future.
So today is 17/08, therefore I would only want to pull data from the CSV that is dated between 17/08 to 24/08.
Although Powershell sort of handles datetime objects in UK format if you tell it to, I seem to be unable to then manipulate the date to add on 7 days.
Here is my current code:
$today = Get-Date
$thisWeek = $today.AddDays(7)
$thisWeekString = $thisWeek.ToString()
$dateParts = $thisweekString -split " "
$weekFinal = $dateParts[0]
$import = Import-Csv #("\\location\EmailCSV.csv") | Where-Object {$_.collectionDate -lt $weekFinal}
Powershell correctly adds 7 days to the datetime to make it 24/08, and then when converting it to a string and removing the time from it, it correctly sets the variable as 24/08/2018. But when I then go to compare them in the Import cmdlet, it just returns all data in the CSV, rather than dates less than 24/08.
I also know Powershell can compare these, because if I create a separate variable $otherDate with 24/08/2018 in it, and then create an if statement that checks if $weekFinal is greater or less than $otherDate, it correctly runs the statement when true.
I've tried using both Where and Where-Object in the Import-Csv cmdlet, but both have returned the same results.
How do I get Powershell to correctly compare $_.collectionDate and $weekFinal to filter the imported data from the csv?
It is easiest to perform all calculations and comparisons using [datetime] instances - avoid string operations (except for converting a string representation of a date to a [datetime] instance).
First, express today's date and 1 week from now as a [datetime] instance without a time-of-day component:
$today = (Get-Date).Date # Today's date, without a time component (midnight)
$oneWeekFromToday = $today.AddDays(7)
Then use [datetime]::Parse() to convert the invariably string-typed CSV column value of interest to a [datetime] instance so you can perform proper date-comparison.
$import = Import-Csv \\location\EmailCSV.csv | Where-Object {
$thisDate = [datetime]::Parse($_.collectionDate)
# Process this row if its date falls between today and 1 week from now, inclusively.
$thisDate -ge $today -and $thisDate -le $oneWeekFromToday
}
Important: use [datetime]::Parse('...'), not a [datetime] '...' cast, because only [datetime]::Parse() respects the current culture's date and time formats; by design, PowerShell's casts and string interpolation always use the invariant culture, irrespective of the current culture - for more information, see this answer of mine.
Try casting the strings to [datetime] in your comparison. When using a sample set of data, I was able to get the expected results.
$import = Import-Csv #("\\location\EmailCSV.csv") | Where-Object {[datetime]$_.collectionDate -lt [datetime]$weekFinal}
I have a CSV file with the following data
"Date","Time","Name","SourceIP","DestinationIP"
"Sep 1","03:55:57","mmt-5","172.16.48.158","22.22.22.22"
"Sep 1","03:55:57","mmt-5","172.16.48.158","22.22.22.22"
"Sep 1","03:55:57","mmt-5","172.16.48.158","22.22.22.22"
"Sep 1","03:55:57","mmt-5","172.16.48.158","22.22.22.22"
I would like to convert the date into something more usable like 09-01-2016 (the year would be the current year).
How can I accomplish this?
That's easy using the [DateTime] class's ParseExact method. You supply the string that is a date, you tell it how the date is formatted, and you provide a culture or provider or something, but I always just use $null.
[datetime]::ParseExact("Sep 1","MMM d",$null)
That comes out to:
Thursday, September 1, 2016 12:00:00 AM
So you could just do something like:
$Array | ForEach{[datetime]::ParseExact($_.Date,"MMM d",$null)}
And that would convert each entry's Date property to a valid [datetime] object. Then you just format it however you want:
$Array | ForEach{[datetime]::ParseExact($_.Date,"MMM d",$null).ToString("M-d-yyyy")}
That would output:
9-1-2016
Or for the exact thing you asked for use "MM-dd-yyyy" to get 09-01-2016.
Edit: Thanks to wOxxOm for educating me about the third parameter's necessity when dealing with non-localized date formats! So, if this needs to be localized for other cultures, you will need to include that last parameter. That can be done as such:
$Culture = [cultureinfo]::GetCultureInfoByIetfLanguageTag('en-US')
$Array | ForEach{[datetime]::ParseExact($_.Date,"MMM d",$Culture).ToString("MM-dd-yyyy")}
Edit2: Ok, to replace your current Date field with this information you could pass the array to the Select command, and create a new Date property on the fly, and discard the original, then pass that to Export-CSV:
$Array | Select *,#{l='Date';e={[datetime]::ParseExact($_.Date,"MMM d",$null).ToString("M-d-yyyy")}} -Exclude Date | Export-CSV D-Sample-2.csv -NoType
I have a very odd thing happening in Powershell.
Here is the code:
add-pssnapin windows.serverbackup
$wbs = Get-Wbsummary
$lastbackuptime = $wbs.lastBackupTime
$solution = "Windows Server Backup"
$surl = "https://REDACTED:1338/REDACTED.asp?querysolution=$solution&querylastbackuptime=$lastbackuptime"
write-host $surl
write-host $lastbackuptime
Here is what is output when I run this
https://REDACTED:1338/REDACTED.asp?querysolution=Windows Server Backup&querylastbackuptime=05/07/2013 05:04:12
07/05/2013 05:04:12
Why is powershell swapping the date around when made as part of another variable but not when I output the variable on its own?!
This is a special case with casting a datetime object. When you simply print the date as a string using write-host, that will be equal to running $lastbackuptime.toString(). This method uses the culture of you're computer. In my case, the culture in Region settings for Windows is Norway, so I get the "european" dateformat: dd/mm/yyyy.
However, when you include $lastbackuptime inside a string, it performs a cast to a string-object. In PowerShell(or .Net) it was decided that when casting a datetime-object, it should use a standard format to convert it to string so that the code would run the same no matter what culture the computer was configured with. That's why casting gives you the US format, while toString() and Write-Host gives the "european" format
Ex:
[16:07:43] PS-ADMIN C:\> $d.tostring()
07.05.2013 16:04:17
[16:13:05] PS-ADMIN C:\> write-host $d
07.05.2013 16:04:17
[16:13:12] PS-ADMIN C:\> [string]$d
05/07/2013 16:04:17
To specify the format your datetime should be displayed, you can do something like this:
[16:14:28] PS-ADMIN C:\> $d.tostring("dd/MM/yyyy")
07.05.2013
[16:14:34] PS-ADMIN C:\> "examplestring $($d.tostring("dd/MM/yyyy"))"
examplestring 07.05.2013
Read more here
Check your regional settings, specifically the Short Date & Long Date formats.
On my system, Short Date is MM/dd/yyyy and and Long Date is dddd, MMMM dd,yyyy. Then, running a simplified version of your example:
>$lastbackuptime = get-date;
>$lastbackuptime
Tuesday, May 07, 2013 10:07:42
>$url="http://whatever/redacted.asp?time=$lastbackuptime";
>$url
http://whatever/redacted.asp?time=05/07/2013 10:07:42
When used on its own, the Long Date format is used in returning the date, but when concatenated with (or expanded inside) another string the Short Date format is used.
I just started working with Powershell and I am trying to manipulate a date such that I add two months to the date and set it as a var. Powershell handles this nicely and even handles year rollover. However I am stuck trying to figure out how to also control the format of the date before, during or after adding two months to the date. Both of the statements below give me what I want but i have not been able to figure out how to combine them.
$ndate = (Get-Date).AddMonths(2)
$exp = date -format MM/dd/yyyy
Thank you,
Get-Date (Get-Date).AddMonths(2) -f MM/dd/yyyy
When the -Format operator is not avaiable you can use the ToString method:
(Get-Date).AddMonths(2).ToString('MM/dd/yyyy')