How do I find the properties available from a powershell command? - powershell

I want to find what the possible columns or elements are from the get-service command. I am mostly interested in finding the log on as value a service runs under, but it'd be nice to know how to find others when the need arises.

Use the Get-Member cmdlet - gm in short
Get-Service | gm
Coming to Log On As, I think Get-Service ( or rather the [ServiceController] type)
does not expose it. You can use WMI though:
gwmi win32_service | select name, startname

Related

Get username for PID (ProcessId)

I have a PID for which I want to check its username. I knew that we can use GetOwner(), but it is the valid method for Get-WmiObject Win32_Process. I am using Get-WmiObject -Class Win32_PerfRawData_PerfProc_Process in which there is no way to get username (as per I search online). So, I think to check PID separately is the only way to resolve this.
Can you please tell me how can I get the username of PID or get username inside Win32_PerfRawData_PerfProc_Process?
As it is described in this technet article :Technet you can use the code below.
In the last line you can put the process you want after the get-process command.
e.g. Get-Process outlook | select processname,Id,#{l="Owner";e={$owners[$_.id.tostring()]}}
$owners = #{}
gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user}
Get-Process | select processname,Id,#{l="Owner";e={$owners[$_.id.tostring()]}}
The time it takes depends on how many services are currently running.
Your output will be like:
ProcessName Id Owner
----------- -- -----
OUTLOOK 13128 UserName
Hope that helps.
Kind regards.

Querying Windows Update Errors using PowerShell Get-WinEvent or Get-WMIObject

Trying to create a simple Windows Update error query using Get-WinEvent (although I would prefer querying a WMI Object for use with SCUP):
get-winevent -logname System| Where-Object {$_.ProviderName -eq "Microsoft-Windows-WindowsUpdateClient"}
This seems to work for the most part. However, it only returns informational events and not errors. Are these located somewhere else and, if so, how would I query them? For some background, there is a specific update failure occurring on approximately 10% of Windows 10 machines in my environment (missing assembly file) and I want to target it so that I can deploy a solution.
A solution using Get-WinEvent is fine, though I would prefer using Get-WMIObject if possible.
You can use the Win32_NTLogEvent like this:
Get-WmiObject Win32_NTLogEvent |?{($_.LogFile -eq 'System') -and ($_.SourceName -eq 'Microsoft-Windows-WindowsUpdateClient') }
Note: You can further filter with Type which will tell you about information or error or warning.
Hope it helps.
I cannot find anything that actually states this but it looks like Get-WinEvent by default only returns information messages. If you want to see the other then you need to tell it to return those. One way to do it is with -FilterHashtable.
Get-WinEvent -FilterHashtable #{LogName='System';Level=1,2}
That would return only warnings and error.
1 - Error
2 - Warning
4 - Information
You can look at the enum [System.Diagnostics.EventLogEntryType] to see where I got the numbers from.
Looking at MS you can see what the hashtable filter supports..
LogName=<String[]>
ProviderName=<String[]>
Path=<String[]>
Keywords=<Long[]>
ID=<Int32[]>
Level=<Int32[]>
StartTime=<DateTime>
EndTime=<DataTime>
UserID=<SID>
Data=<String[]>
*=<String[]>
If your WMI queries are having similar issues then you can do something like this
Get-WmiObject -class Win32_NTLogEvent -filter "(logfile='Application') AND (type='error')"
You can find some tangential examples here
Write a WMI query (this overrides weird event type filters):
Get-WmiObject -Query "Select * from Win32_NTLogEvent" |?{(($_.LogFile -eq 'System') -and ($_.Type -in ("Error", "Warning"))) -and ($_.SourceName -eq 'Microsoft-Windows-WindowsUpdateClient') }
Okay, so after doing some additional research, I stumbled upon this website that sheds some light on the issue I'm running into. Essentially, while most, if not all Windows Events are logged in the C:\Windows\System32\Winevt\logs folder, not all Windows Events are replicated in WMI by default.
In PowerShell, Get-WinEvent appears to use the above folder when querying its event data, whereas Get-EventLog uses the Win32_WinNTLogEvent WMI class.
In my original question, I mentioned that I was unable to query Windows Update error events using Get-WinEvent. This is because I was pointing to the System log file, which does not contain the information. The Microsoft-Windows-WindowsUpdateClient/Operational log file (literal path being C:\Windows\System32\Winevt\logs\Microsoft-Windows-UpdateClient%4Operational.evtx) does contain this information, so my query can simply be changed up using something similar to the following:
Get-WinEvent -logname "Microsoft-Windows-WindowsUpdateClient/Operational" | Where-Object {$_.LevelDisplayName -eq "Error"}
In order to query the same data returned by Get-WinEvent using the Win32_NTLogEvent WMI class, the registry must first be modified. Again, the link I posted in this answer describes the process in greater detail, but essentially I performed the following registry mod:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Microsoft-Windows-WindowsUpdateClient/Operational]
"File"="%SystemRoot%\\System32\\Winevt\\Logs\\Microsoft-Windows-WindowsUpdateClient%4Operational.evtx"
"Primary Module"="Microsoft-Windows-WindowsUpdateClient/Operational"
"Microsoft-Windows-WindowsUpdateClient/Operational"=hex(2):25,00,53,00,79,00,73,00,74,\
00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,\
65,00,6d,00,33,00,32,00,5c,00,77,00,65,00,76,00,74,00,61,00,70,00,69,00,2e,\
00,64,00,6c,00,6c,00,00,00
Note: The "Microsoft-Windows-WindowsUpdateClient/Operational" Expanded String (REG_EXPAND_SZ) at the end there is pointing to %SystemRoot%\system32\wevtapi.dll
Once the registry was modified, I was able to query the error events as follows:
Get-WmiObject -query "SELECT * FROM Win32_NTLogEvent WHERE LogFile='Microsoft-Windows-WindowsUpdateClient/Operational' AND Type='Error'"
Somewhat of a pain considering that Windows Update errors should probably be present in the Win32_NTLogEvent WMI class by default (ah, Microsoft). Still, this essentially resolves my question.
One additional point to mention. The website above states that, upon editing the registry, you'd be able to query the new events immediately. I had to reboot my machine first.

Command to query services

I wrote a powershell command to audit services in HyperV HV's and
$Auditservices = get-service -computername $ComputerName -name "*iscsi*","*winrm*","*scvmm*","*vmms*","vss"| Select-Object Status, Name, MachineName
And output for the same is showing like below
MSiSCSI SCVMMAgent vmms vss WinRM Running Running Running Running Running
Is there anyway we can change the output to this format ?
MSiSCSI,Running
SCVMMAgent,Running
vmms,Running
vss,Running
WinRM,Running
If you really want to get output exactly as you've described, you'll need to create some strings:
$Auditservices | Foreach-Object {"$($_.Name),$($_.Status)"}
You might instead actually want it in CSV format? If so, pipe it to Export-CSV

How to check multiple services on different servers in powershell scripting?

I have 3 servers
server a, server b, server c
I want to check 3 services,
service = serva, servb, servc
server a contains serva and servb
server b contains servb and serv c
server c contains servc only
I already seen a script for checking different services on different servers but i cannot think of a way to edit it to fit to my needs. Can anyone help me please on how to check multiple servies (some are the same) in different servers?
Here is one way to do this:
$services = #( #{Computername="ServerA"; ServiceName="ServiceA"},
#{Computername="ServerA"; ServiceName="ServiceB"},
#{Computername="ServerB"; ServiceName="ServiceB"},
#{Computername="ServerB"; ServiceName="ServiceC"},
#{Computername="ServerC"; ServiceName="ServiceC"}
)
$services | %{Get-Service -Computername $_.Computername -ServiceName $_.ServiceName}
# Because I used a hashtable with full parameter names for $services, I can do this trick
$services | %{Get-Service #_ }
Now I did a lot of advanced stuff there. We can make this smpler by putting your data in a CSV file. Just use ComputerName and ServiceName as the columns to fit this example. Just have one server and one service on each line.
$services = Import-CSV servicelist.txt
$services | %{Get-Service -Computername $_.Computername -ServiceName $_.ServiceName}
The default output may not show the computer name so it would be a good idea to pipe it to a Select-Object MachineName, Name, Status.

Get user's last logon from sccm with powershell

I'm trying to create wmi query to sccm to get PC, where was user's last logon.
Something like:
Get-WmiObject -namespace $SCCMNameSpace -computer $SCCMServer -query "select lastlogon, PCname from sms_? where LastLogonUserName='$SamAccountName'" | select lastlogon, PCname.
I can see this information in sccm report, but I don't know what class I have to use for a query. I'm using sms_r_system for getting IP and computer name.
Is anyone knew sccm class with this information or sql queries will be better for me?
Which report are you viewing the data with? You might want to open up the report's SQL code, figure out which ConfigMgr SQL views it's referencing, and then translate that to the SCCM WMI class names. The WMI class names closely correlate to the SQL view names.
Use a WMI browser like SAPIEN's free WMI Explorer GUI tool to help explore the root\sms\site_xyz WMI namespace and discover which class you are looking for. You can also use Windows PowerShell to help discover which class contains this property:
gwmi -name root\cimv2 -list | ? { ($_.Properties.Name -join ',') -match 'lastlogon' }
Note: Make sure you're using PowerShell version 3.0 Release Preview for the above command, otherwise it won't work right.