Asked by:
Date calculations using New-TimeSpan

Question
-
I have extended the SCCM inventory on our server to retrieve additional WMI data from clients. We use a DCM rule to update the client machines with the current days data. Inventory is run every day so we will have the latest data usage. I have a problem though that the script for compliance only works for the UK. The US machines have a differen regional and locale set and it seems to affect the way powershell commands work.
# Discovery Script
# Daily Compliance Check for OneDrive folder scan.
$Today = get-date
$Namespace = "ERM"
$Class = "ERMOneDriveFolderScans"
$ClassInfo = Get-WmiObject -Namespace "root\cimv2\ERM" -Class ERMOneDriveFolderScans -ErrorAction SilentlyContinue -ErrorVariable wmiclasserror
$ClassCount = (Get-WmiObject -Namespace "root\cimv2\ERM" -Query "select * from ERMOneDriveFolderScans" -ErrorAction SilentlyContinue -ErrorVariable wmiclasserror | select-object -expandproperty key).count
if ($wmiclasserror -or $ClassCount -eq 0) # Class doesn't exist or no class instances (meaning ERMer has set up one drive yet)
{
$Updated = 0
}
else # update if more than a day old
{
if ($ClassCount -eq 1)
{
if ((New-TimeSpan -start $classinfo.Scan_Date -End (Get-Date -Format "dd-MM-yyyy")).days -gt 0)
{
$Updated = 0
}
else
{
$Updated = 1
}
}
else
{
if ((New-TimeSpan -start $classinfo[0].Scan_Date -End (Get-Date -Format "dd-MM-yyyy")).days -gt 0)
{
$Updated = 0
}
else
{
$Updated = 1
}
}
}
$Updated# Script End
If I run this script on a US machine with the region and local being US with date formant "mm/DD/yyyy the New-TimeSpan will generate and error :[DBG]: PS C:\Tools\Scripts>> (New-TimeSpan -start $classinfo.Scan_Date -End (Get-Date -Format "dd-MM-yyyy")).days
New-TimeSpan : Cannot convert 'System.Object[]' to the type 'System.DateTime' required by parameter 'Start'. Specified method is not supported.
At line:1 char:22
+ (New-TimeSpan -start $classinfo.Scan_Date -End (Get-Date -Format "dd- ...
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-TimeSpan], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.NewTimeSpanCommand.
This command gives the correct date if machine is in the UK. The start date is a string in the same string format "dd-MM-yyyy".Does anyone know how to perform a universal date calculation as we have machines in multiple time zones but will was one constant date format when reporting?
Regards,
Nigel- Moved by Bill_Stewart Thursday, January 25, 2018 9:51 PM This is not SCCM forum
Tuesday, October 17, 2017 2:24 PM
All replies
-
I must also add the $classinfo[0...].Scan_Date array contains all users that have been using the machine. When I write the WMI values it is stored as a string in the format "dd-MM-yyyy"
Regards,
Nigel
Tuesday, October 17, 2017 2:28 PM -
You may need to convert the object in to a DateTime object. Try
New-TimeSpan -start (($classinfo.Scan_Date).ToDateTime()) -End (Get-Date -Format "dd-MM-yyyy")).days
Regards Mark
Tuesday, October 17, 2017 2:33 PM -
What format is the "$classinfo.Scan_Date " in. Is it WMI datetime format or something else?
$classdate = (Convert from unknown format)$classinfo.Scan_Date
(New-TimeSpan -start $classdate -End [DateTime]::ToDay).days\_(ツ)_/
Tuesday, October 17, 2017 2:39 PM -
PS C:\Tools\Scripts> $classinfo[0].Scan_Date.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.ObjectTuesday, October 17, 2017 3:55 PM -
I know it is a string but what is the format. Post the string.
\_(ツ)_/
Wednesday, October 18, 2017 1:29 AM -
The format is "dd-MM-yyyy"Wednesday, October 18, 2017 9:43 AM
-
Take a look at this blog post for information about dealing with dates in different formats: https://blogs.technet.microsoft.com/heyscriptingguy/2011/08/25/use-culture-information-in-powershell-to-format-dates/
As the script is running on the client, you should be able to do something like this:
$culture = New-Object System.Globalization.CultureInfo "en-gb" $StartDate = Get-Date -Date ($class.Scan_Date) -Format $culture.DateTimeFormat.ShortDatePattern
New-TimeSpan -start $StartDate -End (Get-Date -Format "dd-MM-yyyy")).days
Regards Mark
Wednesday, October 18, 2017 10:40 AM -
Get-Date cannot convert a WMI date string. Use Mangement datetime converter class;
[System.Management.ManagementDateTimeConverter]
\_(ツ)_/
Wednesday, October 18, 2017 11:19 AM -
The format is "dd-MM-yyyy"
Is that the string you have or is that what you want?
\_(ツ)_/
Wednesday, October 18, 2017 11:20 AM -
Hi,
That is the format I want.
Wednesday, October 18, 2017 12:47 PM -
I used string type because when create a WMI instance using a DateTime object defining a property it throws up a 'type mismatch'
i.e
$newClass = New-Object System.Management.ManagementClass ("root\cimv2\$Namespace", [String]::Empty, $null);
$newClass["__CLASS"] = $Class
$newClass.Qualifiers.Add("Static", $true)
$newClass.Properties.Add("Key", [System.Management.CimType]::String, $false)
$newClass.Properties["Key"].Qualifiers.Add("Key", $true)
# $newClass.Properties.Add("Scan_Date", [System.Management.CimType]::String, $false)
$newClass.Properties.Add("Scan_Date", [System.Management.CimType]::DateTime, $false)
$WMIURL = 'root\cimv2\'+$Namespace+':'+$Class
$PushDataToWMI = ([wmiclass]$WMIURL).CreateInstance()
$PushDataToWMI.Scan_Date = Get-Date$PushDataToWMI.Put()
Wednesday, October 18, 2017 12:52 PM -
As jrv pointed out you will need to convert between a WMI date and a .NET date format. Using the following code I was able to create the class with a WMI datetime property, set an instance and then convert that back again.
$Class = "Test_Class" $newClass = New-Object System.Management.ManagementClass ("root\cimv2", [String]::Empty, $null) $newClass["__CLASS"] = $Class $newClass.Qualifiers.Add("Static", $true) $newClass.Properties.Add("Key", [System.Management.CimType]::String, $false) $newClass.Properties["Key"].Qualifiers.Add("Key", $true) $newClass.Properties.Add("Scan_Date", [System.Management.CimType]::DateTime, $false) $newClass.Put() # Get .NET DateTime $a = Get-Date # Convert to WMI DateTime $Date = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($a) Set-WmiInstance -Class $Class -Arguments @{Scan_Date=$a} $c = Get-WmiObject -class $Class # Convert WMI DateTime to .NET DateTime [System.Management.ManagementDateTimeConverter]::ToDateTime($c.Scan_Date)
Regards Mark
Thursday, October 19, 2017 12:27 PM