How to discover device properties and their powershell/WMI equivalent? - powershell

I have this powershell code (I didn't write it) :
$nics = Get-WmiObject Win32_NetworkAdapter -filter "AdapterTypeID = '0' `
AND PhysicalAdapter = 'true' `
AND NOT Description LIKE '%Centrino%' `
AND NOT Description LIKE '%wireless%' `
AND NOT Description LIKE '%WiFi%' `
AND NOT Description LIKE '%Bluetooth%'"
foreach ($nic in $nics)
{
$nicName = $nic.Name
...
}
Question
How did the author knew that the NIC has those properties :
Win32_NetworkAdapter
AdapterTypeID
PhysicalAdapter
Description
In other words : How can I inspect all the properties that NIC/Other_Device has ?

get-member or (gm) gets you all properties:
PS C:\Users\bjorn> Get-WmiObject Win32_NetworkAdapter | gm
TypeName: System.Management.ManagementObject#root\cimv2\Win32_NetworkAdapter
Name MemberType Definition
---- ---------- ----------
PSComputerName AliasProperty PSComputerName = __SERVER
Disable Method System.Management.ManagementBaseObject Disable()
Enable Method System.Management.ManagementBaseObject Enable()
Reset Method System.Management.ManagementBaseObject Reset()
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time)
AdapterType Property string AdapterType {get;set;}
AdapterTypeId Property uint16 AdapterTypeId {get;set;}
AutoSense Property bool AutoSense {get;set;}
Availability Property uint16 Availability {get;set;}
...
or with e.g. the ISESteroids plugin:

Related

Win Powershell get list of active local users

I want to get the list of active local users on the windows server. When I do Get-LocalUser, I get following output
Name Enabled Description
---- ------- -----------
DefaultAccount False A user account managed by the system.
Guest False Built-in account for guest access to the computer/domain
labadmin True Built-in account for administering the computer/domain
Test True
WDAGUtilityAccount False A user account managed and used by the system for Windows Defender Application Guard scen...
I tried GetLocalUser -Enabled True and got following error
Get-LocalUser : A parameter cannot be found that matches parameter name 'Enabled'.
At line:1 char:79
+ ... ng = New-Object Text.UTF8Encoding $false; Get-LocalUser -Enabled True
+ ~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-LocalUser], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetLocalUserCommandnon-zero return code
What is the correct parameter to filter out the disabled users?
Get-Help -Name "Get-LocalUser" (also written help get-localuser) will show you that the only available parameters are:
SYNTAX
Get-LocalUser [[-Name] <String[]>] [<CommonParameters>]
Get-LocalUser [[-SID] <SecurityIdentifier[]>] [<CommonParameters>]
And there is no parameter to filter on the enabled users. You need to get the results back, then filter afterwards. From the results in your question, the Enabled column shows you that the user objects probably have a property called Enabled which you can check for the filtering:
$users = Get-LocalUser
$enabledUsers = $users | Where-Object { $_.Enabled }
If you did not know that, or that did not work because the column name is not exactly the same as the property name, you could run $users | Get-Member to see what properties the user objects have, and then look through them for ones to check. Enabled is shown in the result:
TypeName: Microsoft.PowerShell.Commands.LocalUser
Name MemberType Definition
---- ---------- ----------
Clone Method Microsoft.PowerShell.Commands.LocalUser Clone()
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
AccountExpires Property System.Nullable[datetime] AccountExpires {get;set;}
Description Property string Description {get;set;}
Enabled Property bool Enabled {get;set;}
FullName Property string FullName {get;set;}
LastLogon Property System.Nullable[datetime] LastLogon {get;set;}
Name Property string Name {get;set;}
ObjectClass Property string ObjectClass {get;set;}
PasswordChangeableDate Property System.Nullable[datetime] PasswordChangeableDate {get;set;}
PasswordExpires Property System.Nullable[datetime] PasswordExpires {get;set;}
PasswordLastSet Property System.Nullable[datetime] PasswordLastSet {get;set;}
PasswordRequired Property bool PasswordRequired {get;set;}
PrincipalSource Property System.Nullable[Microsoft.PowerShell.Commands.PrincipalSource] PrincipalSource {ge...
SID Property System.Security.Principal.SecurityIdentifier SID {get;set;}
UserMayChangePassword Property bool UserMayChangePassword {get;set;}

Why is this powershell -or filter not working?

I have an object saved to a variable with lots of records. I want to filter the object results based on two columns. The same value can appear in either column. The filter works correctly on the HostName column. But doesn't correctly filter on the RecordData column. There is a result there but the filter isn't retrieving it.
Below is an example of the results missing. All 4 rows should appear in the first query. I can't find what I'm doing wrong. Can someone help?
PS H:\> $DNSRecord | where { ($_.HostName -like "*gcod049*") -or ($_.RecordData -like "*gcod049*") }
HostName RecordType Type Timestamp TimeToLive RecordData
-------- ---------- ---- --------- ---------- ----------
gcod049.domainname.com A 1 0 00:20:00 10.26.101.49
gcod049 A 1 0 00:20:00 10.26.101.49
PS H:\> $DNSRecord | where { ($_.hostname -like "*ssrsdev*") }
HostName RecordType Type Timestamp TimeToLive RecordData
-------- ---------- ---- --------- ---------- ----------
ssrsdev.domainname.com CNAME 5 0 01:00:00 gcod049.domainname.com.
ssrsdev CNAME 5 0 01:00:00 gcod049.domainname.com.
**UPDATE: When I use Select or Select-Object with .ToString(), the value is completely different.
PS H:\> $DNSRecord |
Select HostName, RecordData, #{Name="RecordDataString";Expression={$_.RecordData.ToString()}} |
where { ($_.HostName -like "*gcod049*") -or ($_.RecordData -like "*gcod049*") }
HostName RecordData RecordDataString
-------- ---------- ----------------
gcod049.domainname.com DnsServerResourceRecordA DnsServerResourceRecordA
gcod049 DnsServerResourceRecordA DnsServerResourceRecordA
PS H:\> $DNSRecord |
Select-Object -Property HostName, RecordData, #{Name="RecordDataString";Expression={$_.RecordData.ToString()}} |
where { ($_.HostName -like "*ssrsdev*") -or ($_.RecordData -like "*ssrsdev*") }
HostName RecordData RecordDataString
-------- ---------- ----------------
ssrsdev.domainname.com DnsServerResourceRecordCName DnsServerResourceRecordCName
ssrsdev DnsServerResourceRecordCName DnsServerResourceRecordCName
Here the object get-member properties...
$DNSRecord | gm
TypeName: Microsoft.Management.Infrastructure.CimInstance#root/Microsoft/Windows/DNS/DnsServerResourceRecord
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object ICloneable.Clone()
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
GetCimSessionComputerName Method string GetCimSessionComputerName()
GetCimSessionInstanceId Method guid GetCimSessionInstanceId()
GetHashCode Method int GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializab...
GetType Method type GetType()
ToString Method string ToString()
DistinguishedName Property string DistinguishedName {get;}
HostName Property string HostName {get;}
PSComputerName Property string PSComputerName {get;}
RecordClass Property string RecordClass {get;}
RecordData Property CimInstance#Instance RecordData {get;set;}
RecordType Property string RecordType {get;}
Timestamp Property CimInstance#DateTime Timestamp {get;}
TimeToLive Property CimInstance#DateTime TimeToLive {get;set;}
Type Property uint16 Type {get;}
This is from the table view for type DnsServerResourceRecord's RecordData property, from the file DnsServerPsProvider.Format.ps1xml in the folder C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\DnsServer. It has a long list of if/else statements for this property. I have the dnsserver module from installing rsat in windows 10, but I don't know how to get get-dnsserverresourcerecord working.
But you can refer to $_.RecordData.HostNameAlias for CNAME types. Ironically, canonical name means "real name".
elseif( $_.RecordType -eq "CNAME")
{
$_.RecordData.HostNameAlias
}
$DNSRecord | where { $_.HostName -match 'gcod049' -or
$_.RecordData.HostNameAlias -match 'gcod049' }
Or sometimes it's easier to pipe to findstr /i to look for something.
Have you tried forcing powershell to evaluate the -or first with parenthesis inside the where { ... } like this:
$DNSRecord | where { (($_.HostName -like "*gcod049*") -or ($_.RecordData -like "*gcod049*")) }

Powershell Get-EventLog find event with the matching string in its message

I need to look through eventLog security ID 4648, and find the last time the user connected to the machine.
Currently this is my code:
$Values = invoke-command -ComputerName $ComputerName {Get-EventLog -LogName Security -InstanceID 4648 | Select-Object -ExpandProperty Message| ForEach-Object {if($_.Log -match "$String2"){
$_
Break }}}
$Values
The aim was to go through each log until a log where the message has the previously defined username is found, and then stop going through EventLog and return that log.
This is working well, except its not matching the correct log with the specified string.
Is there a way to improve how the matching works? So it actually finds the correct log with the specified user?
# Fill in the regex for the userName
$userName = "userName"
$Values = #(invoke-command -ComputerName $ComputerName {
Get-EventLog -LogName Security -InstanceID 4648 | Where-Object { $_.message -match $Using:userName } | Select-Object -First 1)
}
Your above sample won't work since message is of type string, therefore it doesn't have a Log property. Since we want $userName to be avaiable for read access on the remote machine we can use the $Using: syntax. To break the pipeline "iteration" I'm using Select-Object -First 1 which will return the first object passing the Where-Objectclause.
Resulting from that $Values points to a collection of (deserialized) objects (using the #() operator) of type:
TypeName: System.Diagnostics.EventLogEntry#Security/Microsoft-Windows-Security-Auditing/4648
Which means you can change the -First parameter to e.g. 10 and sort the result on the client machine:
$Values | sort TimeGenerated -Descending
If you want to know which properties are available you can use:
> $Values | gm
TypeName: System.Diagnostics.EventLogEntry#Security/Microsoft-Windows-Security-Auditing/4648
Name MemberType Definition
---- ---------- ----------
Disposed Event System.EventHandler Disposed(System.Object, System.EventArgs)
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Diagnostics.EventLogEntry otherEntry), bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetObjectData Method void ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
ToString Method string ToString()
Category Property string Category {get;}
CategoryNumber Property int16 CategoryNumber {get;}
Container Property System.ComponentModel.IContainer Container {get;}
Data Property byte[] Data {get;}
EntryType Property System.Diagnostics.EventLogEntryType EntryType {get;}
Index Property int Index {get;}
InstanceId Property long InstanceId {get;}
MachineName Property string MachineName {get;}
Message Property string Message {get;}
ReplacementStrings Property string[] ReplacementStrings {get;}
Site Property System.ComponentModel.ISite Site {get;set;}
Source Property string Source {get;}
TimeGenerated Property datetime TimeGenerated {get;}
TimeWritten Property datetime TimeWritten {get;}
UserName Property string UserName {get;}
EventID ScriptProperty System.Object EventID {get=$this.get_EventID() -band 0xFFFF;}
Hope that helps.

PowerShell Script selecting for particular value [duplicate]

This question already has answers here:
Powershell script value fetching
(2 answers)
Closed 5 years ago.
How to get a particular value in PowerShell display ?
Example - When I execute below script I get 6 values i need to get only 4th row value.
Command:
Get-WmiObject win32_logicaldisk -Filter "Drivetype=3
Output:
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 183760687104
Size : 255791026176
VolumeName :
I need to fetch only "183760687104" value. How to achieve it. Also I do not want to have FreeSpace tag also. Just plain value "183760687104".
You just access the field by name:
(Get-WmiObject Win32_LogicalDisk -Filter "Drivetype=3").FreeSpace
Note that Get-WmiObject is deprecated, you should be using Get-CimInstance instead.
(Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3").FreeSpace
If you want to save the value in a variable, just assign it:
$freespace = (Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3").FreeSpace
and then you can use $freespace as you wish. Be careful though as on a system with more than one local disk your expression will return an array of values rather than just a single one, so you may want to subscript the result to choose only the first disk. Either of these expressions will be sure to give you a single number:
PS C:\Users\User> (Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3").FreeSpace[0]
94229651456
PS C:\Users\User> (Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3")[0].FreeSpace
94239125504
If you are ever in doubt about the accessible fields on an object, just pipe the expression through gm (short for Get-Member):
Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3" | gm
will list all available fields.
PS C:\Users\User> Get-CimInstance Win32_LogicalDisk -Filter "Drivetype=3" | gm
TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_LogicalDisk
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object ICloneable.Clone()
Dispose Method void Dispose(), void IDisposable.Dispose()
Equals Method bool Equals(System.Object obj)
GetCimSessionComputerName Method string GetCimSessionComputerName()
GetCimSessionInstanceId Method guid GetCimSessionInstanceId()
GetHashCode Method int GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.SerializationInfo info, Sys...
GetType Method type GetType()
ToString Method string ToString()
Access Property uint16 Access {get;}
Availability Property uint16 Availability {get;}
BlockSize Property uint64 BlockSize {get;}
Caption Property string Caption {get;}
Compressed Property bool Compressed {get;}
ConfigManagerErrorCode Property uint32 ConfigManagerErrorCode {get;}
ConfigManagerUserConfig Property bool ConfigManagerUserConfig {get;}
CreationClassName Property string CreationClassName {get;}
Description Property string Description {get;}
DeviceID Property string DeviceID {get;}
DriveType Property uint32 DriveType {get;}
ErrorCleared Property bool ErrorCleared {get;}
ErrorDescription Property string ErrorDescription {get;}
ErrorMethodology Property string ErrorMethodology {get;}
FileSystem Property string FileSystem {get;}
FreeSpace Property uint64 FreeSpace {get;}
InstallDate Property CimInstance#DateTime InstallDate {get;}
LastErrorCode Property uint32 LastErrorCode {get;}
MaximumComponentLength Property uint32 MaximumComponentLength {get;}
MediaType Property uint32 MediaType {get;}
Name Property string Name {get;}
NumberOfBlocks Property uint64 NumberOfBlocks {get;set;}
PNPDeviceID Property string PNPDeviceID {get;}
PowerManagementCapabilities Property uint16[] PowerManagementCapabilities {get;}
PowerManagementSupported Property bool PowerManagementSupported {get;}
ProviderName Property string ProviderName {get;}
PSComputerName Property string PSComputerName {get;}
Purpose Property string Purpose {get;}
QuotasDisabled Property bool QuotasDisabled {get;}
QuotasIncomplete Property bool QuotasIncomplete {get;}
QuotasRebuilding Property bool QuotasRebuilding {get;}
Size Property uint64 Size {get;}
Status Property string Status {get;}
StatusInfo Property uint16 StatusInfo {get;}
SupportsDiskQuotas Property bool SupportsDiskQuotas {get;}
SupportsFileBasedCompression Property bool SupportsFileBasedCompression {get;}
SystemCreationClassName Property string SystemCreationClassName {get;}
SystemName Property string SystemName {get;}
VolumeDirty Property bool VolumeDirty {get;}
VolumeName Property string VolumeName {get;set;}
VolumeSerialNumber Property string VolumeSerialNumber {get;}
PSStatus PropertySet PSStatus {Status, Availability, DeviceID, StatusInfo}

Can't access Environment Variable from Remote Server with PowerShell

I have a script to query a list of remote windows servers to retrieve the value of an Environment Variable I have created.
I can see that the variable is indeed there because I can see it when I print all variables: $EnvObj:
try
{
$Name="MY_VAR"
$VerbosePreference="Continue"
# Read a list of server names
$file = New-Object System.IO.StreamReader -Arg "C:\Users\foo\Documents\test.txt"
while ($Computer = $file.ReadLine())
{
if(!(Test-Connection -ComputerName $Computer -Count 1 -quiet))
{
Write-Verbose "$Computer is not online"
Continue
}
try
{
$EnvObj = #(Get-WMIObject -Class Win32_Environment -ComputerName $Computer -EA Stop)
if(!$EnvObj)
{
Write-Verbose "$Computer returned empty list of environment variables"
Continue
}
if($Name)
{
Write-Verbose "Looking for environment variable with the name $name"
$Env = $EnvObj | Where-Object {$_.Name -eq $Name}
# None of these work but printing $EnvObj shows that $Name ("MY_VAR") is there:
$res=[environment]::GetEnvironmentVariable($Name, "Process")
$res1=[environment]::GetEnvironmentVariable($Name, "User")
$res2=[environment]::GetEnvironmentVariable($Name, "Machine")
$res4=$Env:Name
if(!$Env)
{
Write-Verbose "$Computer has no environment variable with name $Name"
Continue
}
}
else
{
Write-Verbose "No environment variable specified. Listing all"
$EnvObj # shows that the requested environment variable is present
}
}
catch
{
Write-Verbose "Error occurred while querying $Computer. $_"
Continue
}
}
}
finally
{
$file.close()
}
The variable itself is owned by <SYSTEM>:
VariableValue Name UserName
------------- ---- --------
1234 MY_VAR <SYSTEM>
But when I try to retrieve it with any of the possible enumerations, it just returns nothing:
None of these work but printing $EnvObj shows that $Name ("MY_VAR") is there:
# .Net way
$res=[environment]::GetEnvironmentVariable($Name, "Process")
$res1=[environment]::GetEnvironmentVariable($Name, "User")
$res2=[environment]::GetEnvironmentVariable($Name, "Machine")
# PS Way
$res4=$Env:Name
... even though when I print the $EnvObj object I can see that $Name is definitely there.
What is wrong?
Your line
$EnvObj = #(Get-WMIObject -Class Win32_Environment -ComputerName $Computer -EA Stop)
Will return an array of [ManagementObject].
To examine all the properties you can pipe one of these objects to Get-Member
$EnvObj[0] | Get-Member
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Environment
Name MemberType Definition
---- ---------- ----------
PSComputerName AliasProperty PSComputerName = __SERVER
Caption Property string Caption {get;set;}
Description Property string Description {get;set;}
InstallDate Property string InstallDate {get;set;}
Name Property string Name {get;set;}
Status Property string Status {get;set;}
SystemVariable Property bool SystemVariable {get;set;}
UserName Property string UserName {get;set;}
VariableValue Property string VariableValue {get;set;}
__CLASS Property string __CLASS {get;set;}
__DERIVATION Property string[] __DERIVATION {get;set;}
__DYNASTY Property string __DYNASTY {get;set;}
__GENUS Property int __GENUS {get;set;}
__NAMESPACE Property string __NAMESPACE {get;set;}
__PATH Property string __PATH {get;set;}
__PROPERTY_COUNT Property int __PROPERTY_COUNT {get;set;}
__RELPATH Property string __RELPATH {get;set;}
__SERVER Property string __SERVER {get;set;}
__SUPERCLASS Property string __SUPERCLASS {get;set;}
PSStatus PropertySet PSStatus {Status, Name, SystemVariable}
ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();
ConvertToDateTime ScriptMethod System.Object ConvertToDateTime();
From this you can see that the value property is called VariableValue.
So,
$EnvLookup = $EnvObj | Where-Object {$_.Name -eq $Name}
$res = $EnvLookup.VariableValue