In Powershell, how do I input <datetime>? - powershell

For example, if I am trying to retrieve eventlog before a specific date and time.
Get-EventLog system -Before (what do I enter here?)
Essentially, what on earth is the format for entering datetimes?

Try it this way:
Get-EventLog System -Before "2/22/2017 7:00am"

According to the docs https://msdn.microsoft.com/powershell/reference/4.0/microsoft.powershell.management/Get-EventLog
-Before requires a type of DateTime
You need to use that. Simple as that.
There are many ways to satisfy this in powershell. Here is one example which can be used for the -Before parameter and another for the -After which takes the same type
$dt = Get-Date
Get-EventLog system -Before $dt -after "2/15/2017 8:27:50 PM" -LogName System

Related

Can someone explain the difference between Get-ComputerInfo -Property OSName vs (Get-ComputerInfo).OSName

I had some old code for documenting the particulars of my machines when I came across Get-ComputerInfo. So I tried to use it (unsuccessfully) and was almost ready to give up when I came across a way to get what I wanted. But now I'm wondering if anyone can help me understand WHY it works the way it does.
It's pretty simple to illustrate:
$OSName1 = Get-ComputerInfo -Property OSName
$OSName2 = (Get-ComputerInfo).OSName
Write-Host $OSName1
Write-Host $OSName2
The above yields:
#{OsName=Microsoft Windows 11 Pro}
Microsoft Windows 11 Pro
I was expecting the 2nd result from the 1st variable. So what's happening differently in those 2 variables? I was expecting them to be the same.
Thanks in advance!
Mark
While the comments do explain what you're already seeing, which is that Get-ComputerInfo -Property OSName returns an object with that property, what isn't obvious is why the command would do that, instead of returning what you expected: the same thing as (Get-ComputerInfo).OSName.
The reason becomes more clear when looking at the help:
Get-Help Get-ComputerInfo
NAME
Get-ComputerInfo
SYNTAX
Get-ComputerInfo [[-Property] <string[]>] [<CommonParameters>]
ALIASES
gin
In the syntax, we can see that -Property takes a String array and not just a single string.
So you can pass an array of property names to return, like this for example:
$info = Get-ComputerInfo -Property OSName, TimeZone, OSProductType
Write-Host $info
And then get:
#{TimeZone=(UTC-05:00) Eastern Time (US & Canada); OsName=Microsoft Windows 10 Enterprise; OsProductType=WorkStation}
Now, I did it that way to match your question, but if you just output the value naturally, or via Write-Output, it would look a lot nicer:
$info
Write-Output $info
TimeZone OsName OsProductType
-------- ------ -------------
(UTC-05:00) Eastern Time (US & Canada) Microsoft Windows 10 Enterprise WorkStation
Or you could format it:
$info | Format-List
TimeZone : (UTC-05:00) Eastern Time (US & Canada)
OsName : Microsoft Windows 10 Enterprise
OsProductType : WorkStation
So the answer why it returns an object with a single property, it's for consistency for when you request multiple properties (or request none and get them all).
This property selection works exactly the same as if you had used Select-Object:
$info = Get-ComputerInfo | Select-Object -Property TimeZone, OSName, OSProductType
It's also worth noting that Get-ComputerInfo is quite slow, and that selecting individual properties does not speed it up in any way, so there is no particular advantage to using the built-in selection vs. selecting after the fact, other than conciseness and readability.
If you need multiple properties, it's definitely not a good idea to make multiple calls to Get-ComputerInfo with different properties selected, as you're retrieving all the same info on every call and then discarding most of it that way.
If you're unsure which properties you need in the first call, just get them all, and choose them later:
$info = Get-ComputerInfo
if ($condition1) {
# do thing with $info.OSName
}
if ($condition2) {
# do thing with $info.TimeZone
}
# etc.

Why do my DateTime objects behave differently?

I have a script that checks for certain logs between two times $startDate and $endDate using Search-UnifiedAuditLog where $startDate is found by checking a line in a .txt file and $endDate is the current time. I run this as shown below.
$startDate = Get-Content $logPath -Last 1
$startDate = [datetime]$startDate
$startDate = $startDate.AddHours(-1)
$endDate = (Get-Date)
This particular script is run every hour, so the time between $startDate and $endDate is two hours (due to the AddHours). If I check the value of these variables, they are indeed two hours apart. However, when I run the script, it goes through the previous 6 hours of logs. This makes me think it is assuming that $startDate is in UTC, and it is converting it to my time zone. Is this what it is doing, and if so, how can I get my script to only check for logs one hour before the time listed in my .txt document?
Turning my comment into an answer
You can check the .Kind property of the $startDate variable.
This property can be either Local, Utc or Unspecified. See DateTimeKind Enum.
In case of Unspecified, since .NET 2.0, "This instance of DateTime is assumed to be a UTC time, and the conversion is performed as if Kind were Utc." as stated in the docs

Get-ADComputer Lastlogondate / Lastlogon

I'm currently asking myself if it is possible to determine the last logon time of any user of a computer object which is connected to an active directory?
I need to find out when any user was logged onto a specific computer which is still online, communicating with the domain but was not in use in the last X days by any user.
I've already tried the following queries:
get-adcomputer $computername -Properties lastlogon | select
#{Name="lastLogon";Expression={[datetime]::FromFileTime($_.'lastLogon')}}
AND
get-adcomputer za31testvmrobin -Properties lastlogondate
I'm expecting the timestamp of the last logondate of a user on a computer object.
Hope you can help me.
I somehow figured it out with help from #boxdog . Thanks for that.
Here is the Powershell Code in one line:
Get-EventLog -LogName Security -InstanceId 4624 -ComputerName $computer |
`where {$_.Message -match "Kontoname: USERNAME" -and
`$_.Message -match "Anmeldetyp: 2" } | select -First 1)
Kontoname = Accountname
Anmeldetyp = Logontype (2 means interactive from console with keyboard & mouse)
The tabulator is needed. You can also use wildcards like an asterisk.
I could not find an easier way to get it working. Therefor I had to use the comparison operator "match" to find a string with which I could search within the Message property of the Eventlog.
Unfortunately searching takes some time. Via remote it takes up to 5 minutes each computer which is quiet unsatisfying.
Maybe someone has another solution which is faster or knows a way to work parallel, actually I don't really know how to do that, because I'm getting content with
get-content c:\data\input.txt
Thanks in advance

Change of format Get-Date` PowerShell

How to do Get-Date to show me this format 2018-01-10 and that does not show the time?
I was currently using Get-Format s but it shows me time.
There are several ways to do this. For instance you could use the -Format parameter of the cmdlet:
Get-Date -Format 'yyyy-MM-dd'
You could use the ToString() method of the DateTime object the cmdlet produces:
(Get-Date).ToString('yyyy-MM-dd')
You could also use PowerShell's format operator (-f):
'{0:yyyy-MM-dd}' -f (Get-Date)
Other method (without get-date):
[System.DateTime]::Today.ToString("yyyy-MM-dd")
Powershell Script to get date as requested
get-date -Format yyyy-MM-dd
Following doc will give you brief explanation on formats
https://technet.microsoft.com/en-us/library/ee692801.aspx

Filter EventLog based on date

I am trying to pull out some information from the eventlog through PowerShell based on the date today.
So far I have the code below:
$today = (Get-Date).ToString("dd/MM/yyyy")
Get-EventLog Security | where {$_.EventID -eq 4624} | where {$_.TimeGenerated -eq $today}
Now I have printed the result of today and can confirm that the outputted date is 04/12/2017, I have also printed the date of the TimeGenerated attriubute from the EventID object and that also shows the date in the same format.
Any ideas on where I am going wrong?
The TimeGenerated property holds a DateTime value, not a string, so don't compare it to a date string. Also, you should filter via Get-EventLog parameters whenever possible, because that filtering happens at the source. This is particularly relevant when querying remote eventlogs to reduce the amount of data that is transmitted over the network.
$today = (Get-Date).Date
$tomorrow = $today.AddDays(1)
Get-EventLog -LogName Security -InstanceId 4626 -After $today -Before $tomorrow