Failed to get ComputerName in Powershell Get-Eventlog - powershell

In Security section in Event Viewer, there is a column named "Computer".
I am using powershell to retrieve "all event ID 100" as of yesterday and display columns "event ID" and "computer".
Get-EventLog Security -After "2016-08-25 08:08:08" | Where-Object { ($_.instanceid) -eq 100 } | select-object "computer", "instanceID"
However, it only shows blank records for Computer column.
Please help. Thank you.

Try it with MachineName like so
... select-object "MachineName", "instanceID"
You can find that out when piping your objects to
Get-EventLog ... | Get-Member
where you will find a property MachineName

Related

powershell how do I Create/format a dynamic list from a group membership to use in a for each loop

bit of a noob question.
I have the following cmd which grabs the server members of a group which I can copy into a text list. however as the group changes I need to modify the text list manually.
Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | select name
when I have that output in a text list, the following works fine.
$listpath = "C:\Scripts\servers.txt"
[System.Collections.ArrayList]$list = #(Get-content $listpath)
foreach($ComputerName in $list)
{
Get-Uptime -ComputerName $ComputerName
I want to know if it is possible to use a variable that I can use again in a for each loop. I've tried to do so, however the format of the list is not the same when is goes into a variable, thus the function (get-uptime) against the server doesn't work, anyone know what I can do to format the output so I only get the server name?
EG.
$WSUS_7PM = Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | select name
PS C:\Windows\system32> $WSUS_7PM
name
----
AXXXXX003
BXXXXX005
CXXXXX006
DXXXXX007
PS C:\Windows\system32> foreach($Name in $WSUS_7PM) {Write-Host $Name}
#{name=AXXXXX003}
#{name=BXXXXX005}
#{name=CXXXXX006}
#{name=DXXXXX007}
so when I run the same cmds as above modified with the variable instead of the text list, I get the following as the server name is obviously incorrect.
$listpath = $WSUS_7PM
[System.Collections.ArrayList]$list = #(Get-content $WSUS_7PM)
foreach($ComputerName in $list)
{
Get-Uptime -ComputerName $ComputerName
WARNING: Unable to connect to #{name=AXXXXX003}
WARNING: Unable to connect to #{name=BXXXXX005}
I hope that makes sense to someone, appreciate the help in understanding what the difference is in the object output.
Thanks
Alzoo
When you use Select-Object name you are creating a list of objects with a name property. You can either expand it ahead of time
$WSUS_7PM = Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | Select-Object -ExpandProperty name
or reference the name property later
foreach($Name in $WSUS_7PM.name) {Write-Host $Name}

Using PoSH to get a value, strange results

I am using PoSH to query our Exchange server to return the largest mailbox by users.
My PoSH is:
$test = Get-MailboxDatabase MBX_* -Status | select Name,#{Name="NumberofUsers";Expression={(Get-Mailbox -resultsize unlimited -Database $_.name).Count}} | Sort -Property NumberofUsers | Select Name -First 1
This works in console and returns:
Name
----
MBX_2
However when I run it like this in a script and return the value, it is like this:
$test = Get-MailboxDatabase -Status MBX_*| select Name,#{Name="NumberofUsers";Expression={(Get-Mailbox -resultsize unlimited -Database $_.name).Count}} | Sort -Property NumberofUsers | Select Name -First 1
Write-Host "Using $test"
Using #<Name=MBX_2>
Why is it including the #<Name=> characters and how can I prevent it from doing that? I need to be able to grab just the returned value of "MBX_2" for the next part of my script and I am confused on how to go about this...
You are selecting a single property of the object, but still passing an object. What you need to do is use the -ExpandProperty parameter of the Select-Object cmdlet. Change your Select command to this:
| Select -ExpandProperty Name -First 1
That should give you the results that you desire.

PowerShell - Office365 Calendar REST API v1.0: Search by Subject

I am trying to use PowerShell to query a group calendar and return only a subset of the events based on a specific string in the Subject field.
Currently, I can use the following and get a listing of all of the events:
$events = Invoke-RestMethod -Uri "https://outlook.office365.com/api/v1.0/users/$calendar/calendarview?startDateTime=$(Get-Date)&endDateTime=$((Get-Date).AddDays(1))" -Credential $cred | foreach-object{$_.Value}
$events | Select-Object -Property Subject,Start,End | fl
This is where I get stuck. I am trying to filter these results to where I only return results where Subject -like '*string*'
However, I just cannot seem to get that to work on the Invoke-RestMethod line...
Any help would be GREATLY appreaciated.
Bonus appreciation to anyone who can take the results of the Start and Stop times from this:
2016-04-25T13:00:00Z
to this:
4/25/2016
For reference, I have already tried this:
Get-Date $events.Start -Format 'MM/dd/yyyy'
Which gives this error:
Get-Date : Cannot convert 'System.Object[]' to the type
'System.DateTime' required by parameter 'Date'. Specified method is
not supported.
Because your using a CalendarView (which is a filter of sorts) you can't apply another filter at the REST level so just filter the results eg
$events | Where-Object {$_.Subject -match 'string'} | Select-Object -Property Subject,Start,End | fl
or if you want to use wildcards
$events | Where-Object {$_.Subject -Like '*string*'} | Select-Object -Property Subject,Start,End | fl
With the Start Stop time just CAST them eg
$events | % {([DateTime]$_.Start).ToString("MM/dd/yyyy")}
Cheers
Glen

Powershell search by single and multiple keyword

I have some commands below that do not give any output when looking for specific keywords in Windows Logs using PowerShell.
Get-WinEvent -FilterHashtable #{LogName="Application"} | Select-String "Information"
However, if I only run Get-WinEvent -FilterHashtable #{LogName="Application"}, there are many entries with Information keyword. Select-String -pattern "Information" also does not work.
Ideally I'd like to search for multiple keywords in the above scenario.
You need to do:
Get-WinEvent -FilterHashtable #{LogName="Application"} | ? { $_.leveldisplayname -eq 'Information' }
The Information you're looking for is a property of the object. The Get-WinEvent cmdlet returns a collection of objects, so you need to add the Where-Object or ? to filter on the LevelDisplayName object property.
To answer your new questions:
The leveldisplayname is going to be Information, Error or Warning. You can add either of these or use logic to combine them. In order to search for keywords in a message, using a regex is probably the best approach:
Get-WinEvent -FilterHashtable #{LogName="Application"} | ? message -imatch "keyword1"
To search multiple keywords, you can modify the regex using the OR | operator:
Get-WinEvent -FilterHashtable #{LogName="Application"} | ? message -imatch "keyword1|keyword2|foo|bar"
If you wanted to search for all Error messages containing "foo" or "bar" you could do;
Get-WinEvent -FilterHashtable #{LogName="Application"} | ? { ($_.message -imatch "foo|bar") -and ($_.leveldisplayname -eq 'Error') }

Powershell: How can I extract time from the message field of eventlog?

I'm trying to get unexpected shutdown times of Windows Sever 2008 machines via Get-EventLog in Powershell. I can get close by searching for events with an EventID of 6008 and selecting only message, but I need to parse within the field to grab the time it occurred (not the time the event fired).
I've tried to use replacementstrings[x] but I can't find how to specify the field to use (messages) and can't get a result.
get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30)}| select message
Produces this:
Message
-------
The previous system shutdown at 3:35:32 AM on ‎7/‎29/‎2014 was unexpected.
The previous system shutdown at 3:40:06 PM on ‎7/‎10/‎2014 was unexpected.`
Retrieving all events from a remote host and filtering them on the local machine ususally doesn't perform too well, because that way you transmit tons of unrelated events over the network, just to throw them away. Get-EventLog has options for filtering messages by Event ID or before/after a given timestamp on the source, so better use those for pre-selecting the messages you're actually interested in. The timestamp of the crash can be extracted from the Message field with a regular expression and parsed into a DateTime value via ParseExact():
$log = 'System'
$server = 'svr-name'
$id = [uint64]"0x80000000" + 6008
$date = (Get-Date).AddDays(-30)
$fmt = 'h:mm:ss tt on M\/d\/yyyy'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-EventLog -LogName $log -ComputerName $server -InstanceId $id -After $date | ? {
$_.Message -match 'at (\d+:\d+:\d+ [ap]m on \d+/\d+/\d+) was unexpected'
} | select MachineName, TimeGenerated,
#{n='Crashtime';e={[DateTime]::ParseExact($matches[1], $fmt, $culture)}}
The pipeline produces a list of objects with the properties MachineName, TimeGenerated and Crashtime (the last one being a calculated property). If you collect the output of the pipeline in a variable (e.g. $evt) you can access the Crashtime property of the third object like this:
$evt = .\script.ps1
$evt[2].Crashtime
Using regex, you can pull it out as such.
$Messages = (get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30) }| select message)
$Messages | ForEach-Object {
$Matched = $_.Message -match "([0-9]{1,2}:.*[0-9]{4})"
if ($Matched) {
Write-Output "System rebooted at $($Matches[1])"
}
}
There might be a better way, but I do not know what :)
Example Output from my System
System rebooted at 4:34:30 PM on ‎4/‎20/‎2014
System rebooted at 1:48:38 PM on ‎1/‎21/‎2014
System rebooted at 1:37:12 PM on ‎1/‎21/‎2014
System rebooted at 1:22:01 PM on ‎1/‎21/‎2014
System rebooted at 4:41:21 PM on ‎11/‎22/‎2013
More easy
get-eventlog system | where-object {$_.EventID -eq "6008"} | fl