Powershell get timezone with DST - powershell

In powershell I'm using
(Get-Timezone).BaseUtcOffset
to get the UTC offset of a computer which gives me +1h for my timezone. That is technically correct since I'm in CET in winter (UTC+1) and CEST in summer (UTC+2). Right now tho it is DST, so CEST (UTC+2) for me so I'm wondering how I could get this information in powershell since the above command tells me that my timezone is UTC+1 and doesn't mention DST at all.
As a workaround I currently use
$date = Get-Date
($date - $date.ToUniversalTime()).TotalMinutes
to get the offset from UTC of my timezone with DST. It evaluates to +120 minutes which is exactly what i need.
Output of Get-Timezone:
Id : W. Europe Standard Time
DisplayName : (UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien
StandardName : Mitteleuropäische Zeit
DaylightName : Mitteleuropäische Sommerzeit
BaseUtcOffset : 01:00:00
SupportsDaylightSavingTime : True
Output of $date - $date.ToUniversalTime():
Days : 0
Hours : 2
Minutes : 0
Seconds : 0
Milliseconds : 0
Ticks : 72000000000
TotalDays : 0,0833333333333333
TotalHours : 2
TotalMinutes : 120
TotalSeconds : 7200
TotalMilliseconds : 7200000

Yes, you can use the static method IsDaylightSavingTime on the TimeZoneInfo class to get this information from a desired DateTime:
$now = [DateTime]::Now
[System.TimeZoneInfo]::Local.IsDaylightSavingTime($now) # Returns $True or $False

thank you Bender the Greatest you got me on the right path. The class System.TimeZoneInfo has a function that does what i want:
[System.TimeZoneInfo]::Local.GetUtcOffset((Get-Date)).TotalMinutes
gives me +120 minutes

Related

print strings and variables in powershell for loop

I need to extract an alerts from rest api and sent it to a file with powershell
I was able to extract the alerts outputs looping the xml file:
foreach ($c in $temp){$c.timeOfAlertFormatted,$c.parent,$c.child,$c.category,$c.servicePlanDisplayName,$c.message}
Thu 09/19/2019 12:00:19 AM
IL
Servername
Phase Failure
Gold
One or more source luns do not have a remote target specified/mapped.
Wed 09/18/2019 02:18:25 PM
IL
Server2
Phase Failure
Gold
One or more source luns do not have a remote target specified/mapped
I am new to PS , what i want to achieve is to add descriptive string
to each filed, i.e:
Time: Thu 09/19/2019 12:00:19 AM
Country: IL
Server: servername
etc ,the rest of the fields.
i tried :
foreach ($c in $temp){Write-Host "Time : $($c.timeOfAlertFormatted)"}
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time :
Time : Thu 09/19/2019 12:00:19 AM
its printing empty "Time" fields
here is example of the xml:
It looks like you have already loaded the xml and filtered out the properties you need in a variable $temp.
I think what you want can be achieved by doing:
$temp | Select-Object #{Name = 'Time'; Expression = {$_.timeOfAlertFormatted}},
#{Name = 'Country'; Expression = {$_.parent}},
#{Name = 'ServerName'; Expression = {$_.child}},
Category,ServicePlanDisplayName, Message
The above should output something like
Time : Thu 09/19/2019 12:00:19 AM
Country : IL
ServerName : Servername
Category : Phase Failure
ServicePlanDisplayName : Gold
Message : One or more source luns do not have a remote target specified/mapped.
Time : Wed 09/18/2019 02:18:25 PM
Country : IL
ServerName : Server2
Category : General Failure
ServicePlanDisplayName : Gold
Message : One or more source luns do not have a remote target specified/mapped.
If your variable $temp is NOT what I suspect it to be, please edit your question and show us the XML aswell as the code you use to extract the alerts from it.

Improving the speed of PowerShell commands in Windows 2016

Example of a problem:
Measure-Command { Get-VMSwitch -SwitchType "External" }
Windows 2012 and 2016 have the same hardware and CPU load is ~50%
Windows Server 2016 (3 external Switches)
Days : 0
Hours : 0
Minutes : 0
Seconds : 6
Milliseconds : 377
Ticks : 63779086
TotalDays : 7.38183865740741E-05
TotalHours : 0.00177164127777778
TotalMinutes : 0.106298476666667
TotalSeconds : 6.3779086
TotalMilliseconds : 6377.9086
Windows Server 2012R2 (3 external Switches)
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 376
Ticks : 13762494
TotalDays : 1.59288125E-05
TotalHours : 0.0003822915
TotalMinutes : 0.02293749
TotalSeconds : 1.3762494
TotalMilliseconds : 1376.2494
Windows 2012R2 with a greater or equal CPU load is 6 times faster.
Windows Server 2016 (9 external Switches)
Days : 0
Hours : 0
Minutes : 1
Seconds : 6
Milliseconds : 168
Ticks : 661689307
TotalDays : 0.000765844105324074
TotalHours : 0.0183802585277778
TotalMinutes : 1.10281551166667
TotalSeconds : 66.1689307
TotalMilliseconds : 66168.9307
Windows 2016 slower now 48 times! :)
In Windows 2016 Meltdown/Specter fixes are disabled.
Is there any option for improving the performance of powershell commands in Windows 2016?
Thanks.
Well, I found another solution. It's using bottlenecks through WMI.
The WMI msvm-ethernetswitchport class can provide all the VMSwitches elements, where we can already get the same information that Powershel CMD Get-VMSwitch provides.
https://learn.microsoft.com/en-us/windows/desktop/hyperv_v2/msvm-ethernetswitchport and etc.
A simple example:
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\virtualization\\v2");
ObjectQuery query = new ObjectQuery("SELECT * FROM Msvm_EthernetSwitchPort");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
Console.WriteLine("DeviceID : {0}", m["DeviceID"]);
Console.WriteLine("ElementName : {0}", m["ElementName"]);
}
It's sad that PowerShell in Windows 2016 runs so slowly...
In fact, through WMI there are so many options how to get this data.
https://learn.microsoft.com/en-us/windows/desktop/hyperv_v2/hyper-v-networking-api

How to format output to DD, HH, MM

I'm trying to work out a devices up time using PowerShell. My code is as so:
$wmi = Get-WmiObject -Class Win32_OperatingSystem
$upTime = $wmi.ConvertToDateTime($wmi.LocalDateTime) – $wmi.ConvertToDateTime($wmi.LastBootUpTime)
When I call $upTime, it returns the following:
Days : 0
Hours : 1
Minutes : 8
Seconds : 5
Milliseconds : 311
Ticks : 40853110010
TotalDays : 0.0472836921412037
TotalHours : 1.13480861138889
TotalMinutes : 68.0885166833333
TotalSeconds : 4085.311001
TotalMilliseconds : 4085311.001
While I can see the up time, I need to specifically format the output to D:dd, H:hh, M:mm as I will be automatically feeding this into a monitoring system, but after much searching on here, google etc, I can't see how to achieve this. Can anyone suggest how to go about doing this?
Try:
"D:{0:dd}, H:{0:hh}, M:{0:mm}" -f $upTime
alternatively, if you like to escape lots of things:
$upTime.ToString('\D\:dd\,\ \H\:hh\,\ \M\:mm')
This will format the string to have 2 leading zeros when ether days, hours or seconds is 0. And 1 leading zero if they are 1-9.
"D:01, H:02, M:23"
You can format it in normal .NET style
$UptimeStr = $Uptime.ToString("ddd:dd, H:hh, mmm:mm")
or
$UptimeStr = '{0:ddd:dd, H:hh, mmm:mm}' -f $Uptime
If the above formatting is not what you wanted the formatting is explained on MSDN

How to get a child item into a variable on its own

I am relatively sure this is quite easy to do but my google fu is not running strong
At the moment I am doing:
add-pssnapin windows.serverbackup
get-wbsummary
This returns me:
NextBackupTime : 07/09/2012 12:00:00
NumberOfVersions : 210
LastSuccessfulBackupTime : 06/09/2012 21:00:13
LastSuccessfulBackupTargetPath : \\?\Volume{bf315689-e5ed-11e1-a376-d067e5f384ea}
LastSuccessfulBackupTargetLabel : SBSERVE 2012_08_21 12:20 DISK_01
LastBackupTime : 06/09/2012 21:00:13
LastBackupTarget : SBSERVE 2012_08_21 12:20 DISK_01
DetailedMessage :
LastBackupResultHR : 0
LastBackupResultDetailedHR : 0
CurrentOperationStatus : NoOperationInProgress
What I want to do is get just the result portion (not its title into a variable) so for example $lastbackuptime = 07/09/2012 12:00:00
PS> $wbs = Get-WBSummary
PS> $lastbackuptime = $wbs.NextBackupTime

Powershell: get-date & [datetime]::FromFileTime returns different values

Why does get-date & [datetime]::FromFileTime returns different values when converting FileTime? An example:
Get-Date 129442497539436142
returns Thursday, March 10, 0411 4:55:53 PM, but
[datetime]::FromFileTime("129442497539436142")
returns Thursday, March 10, 2011 11:55:53 AM
They produce the same result for me, presumably because I'm in GMT.
(FromFileTime parses the time as UTC, Get-Date appears to be using your local time.)
FileTimes are so-called Ticks. 10 million pass every second. Filetime are 0 at midnight, January 1st 1601 (UTC).
Get-date also have ticks, but the base of ticks used by Get-Date is NOT 1601.
It is January 1st year 1.
You can basically identify the 2 different types of ticks by the first digit.
Filetime ticks starts with digit 1 in the rough range of -100 to + 200 years from now.
The ticks using base on January 1st year 0 starts with 6 in roughly the same time range...
In PowerShell you can get verify Jan. 1st year 1 is tick 0 by typing:
[datetime]'0001-01-01' | Select-Object -property Ticks
Get-Date get ticks from 01/01/0001 00:00
[datetime]::FromFileTimeUTC($a) get ticks from 01/01/1601 00:00
You wrote:
returns Thursday, March 10, 0411 4:55:53 PM, but
returns Thursday, March 10, 2011 11:55:53 AM
The difference is 1600 years
This is an example:
$a = ([datetime]::Now).Ticks - ([DateTime]("01/01/0001 00:00")).Ticks
Get-Date $a # get ticks from 01/01/0001 00:00
$a = ([datetime]::Now).Ticks - ([datetime]("01/01/1601 00:00")).Ticks
[datetime]::FromFileTimeUTC($a) # get ticks from 01/01/1601 00:00
It is based on your local "long date" format.
enter image description here
Either you have to change your system "Long Date"
(OR) Use below command
(get-date).tostring("dd/MM/yyyy")
enter image description here
https://technet.microsoft.com/en-us/library/ee692801.aspx
Regards,
Manikandan Boopathy