FilterScript in PowerShell - powershell

I'm using Windows Server 2012 R2 with PowerShell v5 and I've stumbled on some PowerShell behaviour I don't understand.
The following line working correctly and returning results as expected:
Get-WindowsFeature | where -Property "InstallState" -eq "Installed"
This working correctly and returning results as previous:
Get-WindowsFeature | where {$_.Installed}
The following is NOT working, even though it should:
Get-WindowsFeature | where {$_.Available}
But this one is working:
Get-WindowsFeature | where -Property "InstallState" -eq "Available"
I've seen the same behaviour with PowerShell v3 on Windows 7 as well.
Please explain it to me.

Get-WindowsFeature | Get-Member -MemberType Property
TypeName: Microsoft.Windows.ServerManager.Commands.Feature
Name MemberType Definition
---- ---------- ----------
AdditionalInfo Property hashtable AdditionalInfo {get;}
BestPracticesModelId Property string BestPracticesModelId {get;}
DependsOn Property string[] DependsOn {get;}
Depth Property int Depth {get;}
Description Property string Description {get;}
DisplayName Property string DisplayName {get;}
EventQuery Property string EventQuery {get;}
FeatureType Property string FeatureType {get;}
Installed Property bool Installed {get;}
InstallState Property Microsoft.Windows.ServerManager.Commands.InstallState InstallState {get;}
Name Property string Name {get;}
Notification Property Microsoft.Windows.ServerManager.ServerComponentManager.Internal.Notification[] Notification {g...
Parent Property string Parent {get;}
Path Property string Path {get;}
PostConfigurationNeeded Property bool PostConfigurationNeeded {get;}
ServerComponentDescriptor Property psobject ServerComponentDescriptor {get;}
SubFeatures Property string[] SubFeatures {get;}
SystemService Property string[] SystemService {get;}
There is no "Available" property.

Related

How can I find the 'sub properties' of an object in powershell?

I guess I just don't know the proper name of whatever I'm looking for, but this was probably asked a thousand times before.
I started PowerShell not long ago, and I'm struggling to understand where I can find the 'sub properties'(if you can call it those) of an object.
For instance, I was using the VMware PowerCLI, and was tried to figure out how I can find the IP address of a VM.
So for example, I was using the Get-VM command, and when I piped it into get member, I got the following:
PS C:\Users\eitan.rapaport> get-vm "*VRA*" | gm
TypeName: VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl
Name MemberType Definition
---- ---------- ----------
ConvertToVersion Method T VersionedObjectInterop.ConvertToVersion[T]()
Equals Method bool Equals(System.Object obj)
GetClient Method VMware.VimAutomation.ViCore.Interop.V1.VIAutomation VIObjectCoreInterop.GetClient()
GetConnectionParameters Method VMware.VimAutomation.ViCore.Interop.V1.VM.RemoteConsoleVMParams RemoteConsoleVMIn..
GetHashCode Method int GetHashCode()
GetType Method type GetType()
IsConvertableTo Method bool VersionedObjectInterop.IsConvertableTo(type type)
LockUpdates Method void ExtensionData.LockUpdates()
ObtainExportLease Method VMware.Vim.ManagedObjectReference ObtainExportLease.ObtainExportLease()
ToString Method string ToString()
UnlockUpdates Method void ExtensionData.UnlockUpdates()
CoresPerSocket Property int CoresPerSocket {get;}
CustomFields Property System.Collections.Generic.IDictionary[string,string] CustomFields {get;}
DatastoreIdList Property string[] DatastoreIdList {get;}
DrsAutomationLevel Property System.Nullable[VMware.VimAutomation.ViCore.Types.V1.Cluster.DrsAutomationLevel] ..
ExtensionData Property System.Object ExtensionData {get;}
Folder Property VMware.VimAutomation.ViCore.Types.V1.Inventory.Folder Folder {get;}
FolderId Property string FolderId {get;}
Guest Property VMware.VimAutomation.ViCore.Types.V1.VM.Guest.VMGuest Guest {get;}
GuestId Property string GuestId {get;}
HAIsolationResponse Property System.Nullable[VMware.VimAutomation.ViCore.Types.V1.Cluster.HAIsolationResponse]..
HardwareVersion Property string HardwareVersion {get;}
HARestartPriority Property System.Nullable[VMware.VimAutomation.ViCore.Types.V1.Cluster.HARestartPriority] H..
Id Property string Id {get;}
MemoryGB Property decimal MemoryGB {get;}
MemoryMB Property decimal MemoryMB {get;}
Name Property string Name {get;}
Notes Property string Notes {get;}
NumCpu Property int NumCpu {get;}
PersistentId Property string PersistentId {get;}
PowerState Property VMware.VimAutomation.ViCore.Types.V1.Inventory.PowerState PowerState {get;}
ProvisionedSpaceGB Property decimal ProvisionedSpaceGB {get;}
ResourcePool Property VMware.VimAutomation.ViCore.Types.V1.Inventory.ResourcePool ResourcePool {get;}
ResourcePoolId Property string ResourcePoolId {get;}
Uid Property string Uid {get;}
UsedSpaceGB Property decimal UsedSpaceGB {get;}
VApp Property VMware.VimAutomation.ViCore.Types.V1.Inventory.VApp VApp {get;}
Version Property VMware.VimAutomation.ViCore.Types.V1.VM.VMVersion Version {get;}
VMHost Property VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost VMHost {get;}
VMHostId Property string VMHostId {get;}
VMResourceConfiguration Property VMware.VimAutomation.ViCore.Types.V1.VM.VMResourceConfiguration VMResourceConfigu..
VMSwapfilePolicy Property System.Nullable[VMware.VimAutomation.ViCore.Types.V1.VMSwapfilePolicy] VMSwapfile..
As you can see, nothing mentions anything about IP.
I was researching this online, and have found that I should run the following command:
Get-VM | Select Name, #{N="IP Address";E={#($_.guest.IPAddress[0])}}
Which leads me to my question. How can I find the properties under a certain member/property of a command? How could I research the 'sub properties' of 'guest' in that example?
Okay, found it.
In that instance it would be get-vm "*VRA*" | select -ExpandProperty guest | gm
I've been dealing with this for the last two days, so I figured I'd share my solution:
First, I'm saving the VM object to a variable to make it easy to access without searching every time.
$vm = Get-vm -Name steve
To get all the properties of the VM Object
$vm | Select-Object *
If you just want to get the Name you can access it like this:
$vm.Name
If you want to get the Properties of the Guest Object (which is a property of the VM object):
$vm.Guest | Select-Object *
You can access the Properties of the Guest Object through the VM Object like this:
$vm.Guest.VmName
Want the IP addresses of the guest?
$vmip = $vm.Guest.IPAddress
And, because this took me a while to figure out, if that returns ipv4 and ipv6, and you want to filter out the ipv6:
$vmip = $vm.Guest.IPAddress | ?{$_ -notmatch ':'}
Another method of introspection in PowerShell is to just get the class name and then look it up in the API.
PS C:\> $Files = Get-ChildItem *.* -File
PS C:\> $Files[0].GetType().FullName
System.IO.FileInfo
You can then search for that class with either C# or PowerShell to find the API listing.
You can do a similar thing with the VMWare PowerCLI doc. The "all types" list on the left is a list of all the classes used by the module.

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}

How to extract SSL certificate properties

I want a tool which can run on a server, that would extract and return specified properties from an already installed SSL certificate. I am specifically interested in the "issuer" and "thumbprint" properties. I know that I can simply open the certificate's properties dialog and copy these, and then paste them into my app, but to avoid a possibly error-prone manual process when others will be doing this at multiple sites, i would like a tool or script I can call that would simply return the value of a specified property from a specified certificate. I am fine if i need to make a separate call for each desired property. The more turnkey this is, the better. Are there any suggestions, please?
You want to do something like this:
Get-ChildItem Cert:\LocalMachine\Root\ | Select Issuer,Thumbprint
Here is a list of properties you can easily get from System.Security.Cryptography.X509Certificates.X509Certificate2 objects(common certificates).
Name MemberType Definition
---- ---------- ----------
Archived Property bool Archived {get;set;}
Extensions Property System.Security.Cryptography.X509Certificates.X509ExtensionCollection Extensions {get;}
FriendlyName Property string FriendlyName {get;set;}
Handle Property System.IntPtr Handle {get;}
HasPrivateKey Property bool HasPrivateKey {get;}
Issuer Property string Issuer {get;}
IssuerName Property System.Security.Cryptography.X509Certificates.X500DistinguishedName IssuerName {get;}
NotAfter Property datetime NotAfter {get;}
NotBefore Property datetime NotBefore {get;}
PrivateKey Property System.Security.Cryptography.AsymmetricAlgorithm PrivateKey {get;set;}
PublicKey Property System.Security.Cryptography.X509Certificates.PublicKey PublicKey {get;}
RawData Property byte[] RawData {get;}
SerialNumber Property string SerialNumber {get;}
SignatureAlgorithm Property System.Security.Cryptography.Oid SignatureAlgorithm {get;}
Subject Property string Subject {get;}
SubjectName Property System.Security.Cryptography.X509Certificates.X500DistinguishedName SubjectName {get;}
Thumbprint Property string Thumbprint {get;}
Version Property int Version {get;}
DnsNameList ScriptProperty System.Object DnsNameList {get=,(new-object Microsoft.Powershell.Commands.DnsNameProperty -argumentlist $this).DnsNameList;;}
EnhancedKeyUsageList ScriptProperty System.Object EnhancedKeyUsageList {get=,(new-object Microsoft.Powershell.Commands.EnhancedKeyUsageProperty -argumentlist $this).EnhancedKeyUsageList;;}
SendAsTrustedIssuer ScriptProperty System.Object SendAsTrustedIssuer {get=[Microsoft.Powershell.Commands.SendAsTrustedIssuerProperty]::ReadSendAsTrustedIssuerProperty($this);set=$sendAsTrustedIssuer = $args[0]...

Update DLL RC info from powershell

I'm trying to update/add some RC information in DLL directly from the Powershell.
I have found how I can get it but I didn't found how set some field like SpecialBuild or PrivateBuild.
PS C:\> (gi .\mydll.dll).VersionInfo | fl
OriginalFilename : mydll.dll
FileDescription : mydll.dll
...............................
PrivateBuild : 32572
SpecialBuild : NOT_HOTFIX
FileVersionRaw : 17.3.0.12013
ProductVersionRaw : 17.3.0.12013
PS C:\> (gi .\mydll.dll).VersionInfo | gm
TypeName : System.Diagnostics.FileVersionInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Comments Property string Comments {get;}
.................................................
PrivateBuild Property string PrivateBuild {get;}
ProductBuildPart Property int ProductBuildPart {get;}
ProductMajorPart Property int ProductMajorPart {get;}
ProductMinorPart Property int ProductMinorPart {get;}
ProductName Property string ProductName {get;}
ProductPrivatePart Property int ProductPrivatePart {get;}
ProductVersion Property string ProductVersion {get;}
SpecialBuild Property string SpecialBuild {get;}
FileVersionRaw ScriptProperty System.Object FileVersionRaw {get=New-Object System.Version -ArgumentList #(...
ProductVersionRaw ScriptProperty System.Object ProductVersionRaw {get=New-Object System.Version -ArgumentList #(...
As you can see, properties are get only here.
So do you know how I can update theses fields ?
Thanks in advance for your help ;)
Update fields possible with a tool like Resource Hacker, or verpatch, but it's not recommended. If the dll is yours, it's much easier to update it before compilation.
One of the downsides of patching compiled dll is that if it's signed, the signature will no longer be valid. Also, sometimes patching may result in a corrupted dll.
Is there any particular reason why you want to change it after compilation?

Powershell hash table storing values of "System.Collections.DictionaryEntry"

When I execute the command:
$var = #{a=1;b=2}
in Powershell (Version 3), $var ends up with a value of {System.Collections.DictionaryEntry, System.Collections.DictionaryEntry}. Why is this happening? How can I store the values I want to store?
That's because your ISE is enumerating the collection to create the variable-treeview, and the objects returned from a HashtableEnumerator which you get from $var.GetEnumerator() are DictionaryEntry-objects.
$var = #{a=1;b=2}
#Collection is a Hashtable
$var | Get-Member -MemberType Properties
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
#Enumerated objects (is that a word?) are DictionaryEntry(-ies)
$var.GetEnumerator() | Get-Member -MemberType Properties
TypeName: System.Collections.DictionaryEntry
Name MemberType Definition
---- ---------- ----------
Name AliasProperty Name = Key
Key Property System.Object Key {get;set;}
Value Property System.Object Value {get;set;}
Your value (1 and 2) is stored in the Value-property in the objects while they Key is the ID you used (a and b).
You only need to care about this when you need to enumerate the hashtable, ex. When you're looping through every item. For normal use this is behind-the-scenes-magic so you can use $var["a"].