PowerShell command to get installed application/software version - windows

I need to read product version from control panel for specific application. I'm using this command till now.
Get-WmiObject Win32_Product -Filter "Name like 'ISASmaartHub'" | Select-Object -ExpandProperty
after upgrading my system to Windows 11 it is throwing this exception -
Select-Object : Missing an argument for parameter 'ExpandProperty'. Specify a parameter of type 'System.String' and try again.
At line:1 char:82
+ ... -Filter "Name like 'ISASmaartHub'" | Select-Object -ExpandProperty
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Select-Object], ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.SelectObjectCommand
Can anyone please suggest which command I should use to read the version of an application on Windows 11 system.
Thanks in advance!

Prefer using Get-CimInstance over Get-WmiObject for new applications, as WMI is being deprecated.
For WMI\CIM, operator LIKE uses WQL language and should have a % sign as a mark for Any symbols. WQL Like Syntax
Select -ExpandProperty smth means from this big object select only value of smth property. This means, property name MUST present.
Working Example for product named 1C:
Get-CimInstance -Filter 'NAME LIKE "%1C%"' -ClassName 'Win32_Product' |
Select -ExpandProperty 'Version'

Related

How to get only the uptime of the server on Powershell?

I have the following code, It's work when I use directly within powershell:
Get-WmiObject win32_operatingsystem | select #{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)
And it returns:
LastBootUpTime
--------------
14/09/2019 10:41:50
But when I use the command within a Powershell script .ps1 with invoke-command the output returns more informations:
LastBootUpTime PSComputerName RunspaceId
-------------- -------------- ----------
9/14/2019 10:41:50 AM 192.168.0.20 af08d2d8-c4f1-4f85-9d6c-e3f4ffe475c6
Why this happen?
If possible, I'd like without the header LastBootUpTime too.
Invoke-Command will always return additional information, in this case where the command was run and the runspace id. You can always get results into a variable and simply print out the property you want.E.g.
$result = invoke-command {your-command}
$result.LastBootUpTime
or for short
(invoke-command {your-command}).LastBootupTime
Note that when you are using wmi, you do not need to necessarily use invoke-command, you can also directly pass -computer parameter to it to run the command against a remote computer:
Get-WmiObject win32_operatingsystem -computer "remote_computer_name"
Since you're ultimately only interested in the (transformed) property value, there's no need to use Select-Object (whose alias is select) at all - use ForEach-Object instead:
Get-WmiObject Win32_OperatingSystem |
ForEach-Object { $_.ConvertToDateTime($_.LastBootUpTime) }
Note: The extra properties you saw, added by a remote Invoke-Command call with a -ComputerName argument (described below), are still technically present on the result, but they won't display.
That said, the WMI cmdlets were deprecated in PowerShell version 3. Using Get-CimInstance in lieu of Get-WmiObject actually makes the .ConvertToDateTime() call unnecessary (the .LastBootUpTime now directly contains a [datetime] instance), in which case you can simply use Select-Object's -ExpandProperty parameter in order to return the property value only (rather than a [pscustomobject] instance with the requested property):
Get-CimInstance CIM_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime
Note: Get-CimInstance directly supports a -ComputerName argument, so you don't need Invoke-Command -ComputerName for the invocation; unlike the firewall-unfriendly DCOM protocol that the WMI cmdlets use, the CIM cmdlets use the same, firewall-friendly transport as PowerShell remoting.
Or, more succinctly and efficiently, especially in a case such as this where the command returns only a single object, use direct property access:
(Get-CimInstance CIM_OperatingSystem).LastBootUpTime
This answer contrasts the pros and cons of these two approaches and shows other alternatives.
As for what you tried, which generally relates to:
Managing the origin properties automatically added by remote operations:
In remoting scenarios, PowerShell decorates the objects returned with additional properties that provide origin information. These properties are (mostly) of type NoteProperty and are added:
when PowerShell remoting is involved - such as via Invoke-Command -ComputerName in your case.
when CIM cmdlets such as Get-CimInstance are directly used remotely, such as with the -ComputerName parameter.
These properties are:
.PSComputerName (the name of the remote computer on which the code was executed)
Note: On objects returned from remote CIM calls, .PSComputerName appears as a regular property (type Property), not a NoteProperty.
The associated hidden .PSShowComputerName property, which defaults to $true, which explains why you saw a PSComputerName column in the display output.
If you capture the objects before printing them to the screen, you can set the property to $false on them, in which case their .PSComputerName property won't show (but will still be there) - however, the .RunspaceId property may - situationally - still show, and would have to be explicitly excluded - see below.
PowerShell remoting only (not remote CIM calls): .RunspaceId (the ID of the remote runspace)
To exclude these from local display / presence on the object, use the following techniques:
If you're only interested in select properties, make the Select-Object call locally, which, by virtue of locally constructing new [pscustomobject] instances with the properties of interest only, implicitly excludes the remoting-added properties:
Invoke-Command -ComputerName ... { ... } |
Select-Object Name, LastBootUpTime # LOCAL call to Select-Object
If you're interested in all properties except the remoting-added ones, use Select-Object -ExcludeProperty to eliminate them explicitly:
# Get remote output, then locally exclude the remoting-added properties.
Invoke-Command -ComputerName ... { ... } |
Select-Object * -ExcludeProperty PSComputerName, PSShowComputerName, RunSpaceId
Note: Select-Object generally returns [pscustomobject] instances whose properties are static copies of the input objects and which lack the input type's methods.
I found one way! if someone to need here is:
Get-WmiObject win32_operatingsystem | select #{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}|Select-Object -ExpandProperty lastbootuptime
Here is how I used (I'm creating a report in HTML for my database)
write-output "<p> Horario do Ultimo boot: $(Get-WmiObject win32_operatingsystem | select #{LABEL=’LastBootUpTime’;EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}|Select-Object -ExpandProperty lastbootuptime)</p>"
The output was (in my language and region):
Horario do Ultimo boot: 09/14/2019 10:41:50

How to column print only certain row parts of a list in powershell?

I have tried various ways to format the output from a poweshell command and would like to print only some of the row items in the list as part of a a column in one line.
Perhaps more easy to illustrate:
# I want the output from:
Get-CimInstance Win32_OperatingSystem | select Caption,Version,OSArchitecture,InstallDate | fl
Caption : Microsoft HAL 9000
Version : 6.3.9000
OSArchitecture : 64-bit
InstallDate : 2018-08-16 00:50:01
# To look like this:
Microsoft HAL 9000 (6.3.9000) 64-bit [2018-08-16 00:50:01]
How can this be easily accomplished?
(Coincidentally I want all the rows in this case, but a more general answer may be more useful, if it also include rows that we don't want.)
PowerShell usually returns objects and outputs a string representation of it to the host. You want a custom string format output to the host. You can achieve that in various ways, however the fastest way and my recommendation would be to use the -f operator.
$OS = Get-CimInstance Win32_OperatingSystem
'{0} ({1}) {2} [{3}]' -f $OS.Caption, $OS.Version, $OS.OSArchitecture, $OS.InstallDate
With here-strings use can do the same with multi-line.
$OS = Get-CimInstance Win32_OperatingSystem
#'
My OS is {0} {1})
Architecture --> {2}
Installation Date: [{3}]
'# -f $OS.Caption, $OS.Version, $OS.OSArchitecture, $OS.InstallDate
However, you should work with objects as much as - and as long as it is possible.
I would belive this should work for you:
$temp = (Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, OSArchitecture,InstallDate)
The Select-Object makes sure that you get the desired properties. Having a variable with all the details in it, we can concatenate it like this:
"$($temp.Caption) ($($temp.version)) $($temp.OSArchitecture) [$($temp.InstallDate.ToString("yyyy-MM-dd hh:mm:ss"))]"
Simply use Format-Table instead of Format-List. They both support a list of properties you want to see. So if you don't want all columns, list the ones you want.
# 'default' properties in a table
Get-CimInstance Win32_OperatingSystem | ft
# only some properties in a table
Get-CimInstance Win32_OperatingSystem | ft Caption, OSArchitecture
# without table headers
Get-CimInstance Win32_OperatingSystem | ft Caption, OSArchitecture -HideTableHeaders
# all properties in a list (because there are too many for a table)
Get-CimInstance Win32_OperatingSystem | fl *

Grab the latest volume using PowerShell

I'm struggling trying to grab the latest volume/Drive using PowerShell
I have a result of a PowerShell look like this
PS C:\Users\me> Get-WMIObject Win32_Volume | select Name
Name
----
C:\
D:\
E:\
\\?\Volume{021a6bbd-0b97-4973-824a-7c635e362f09}\
\\?\Volume{bae1c1d6-59c3-44b1-9360-b7d3101c0e92}\
PS C:\Users\me>
If I want to access just this
E:
How can I filter out to :\ with the highest alphabetical order ?
I've been trying so many options using Select-String, but seems to get worse result.
The ones you want don't start with "\\". The drive letters may be returned in any order, so you need to sort them and take the last one:
Get-WMIObject Win32_Volume | Where-Object {$_.Name -NotLike '\\*'} | select Name | Sort-Object -Property Name | Select-Object -Last 1
Or, if the drive letter is known to be in the range A to Z, then it would be more sensible to use -Like '[A-Z]*' instead of -NotLike '\\*'.
Try something like this
Get-WMIObject Win32_Volume | where {$_.Name -eq "E:\"}
this should give you a list of objects wich you can access like an array. Also there is a lot of useful information here https://technet.microsoft.com/en-gb/library/2007.04.powershell.aspx

PowerShell Script works in Windows 10 but not on Windows Embedded Standard

I have the following script work in windows 10 but not on windows Embdedded Standard:
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$Path1= "TEST\TESTLog_$(get-date -f yyyy-MM-dd).txt"
$AffPBS= Get-Process "LLCService.exe" | Select-Object ProcessorAffinity
$AffLC= Get-Process "LCService.exe" | Select-Object ProcessorAffinity
$AffinityLLCFinal = "LLC " + $AffPBS
$AffinityLCFinal = "LC " + $AffLC
$FinalOutput = $LogTime+" " +$AffinityLLCFinal +" " + $AffinityLCFinal
$FinalOutput | Out-File -Append $Path1
I have run the Powershell_ISE as administrator and also set Set-ExecutionPolicy RemoteSigned.
The results I'm getting on Windows 10:
10-09-2017_03-31-10 LLC #{ProcessorAffinity=63} LC #{ProcessorAffinity=63}
THe results I'm getting on Windows 7:
10-09-2017_11-23-26 LLC LC
It seems like the Get-Process isn't working on Windows Embedded Standard. Is there any other way of doing this.
Win 10 has PS version 5.1.
Win 7 could have 2.0 or 3.0. You can try to upgrade it. If not, in older Versions, you would have to use Select-object -ExpandProperty "ProcessorAffinity" instead of simply using Select-object "ProcessorAffinity".
You could also chose to run it from win 10 and specify the Win7 computer using the -ComputerName parameter of Get-Process. However, you cannot specify credentials if the win 7 requires different creds that what you are logged on with.
In that case you can use Get-WMIObject -Class Win32_Process -ComputerName "Win7Computer" -Credential $PSCredentialObject but that will give you a slightly different results. I Could not find the "Processor Affinity " Property on it.

Powershell 3.0 : Alternative to "Get-Volume"

I'm trying to get various properties for each hdd-volume on the computer.
I was using the cmdlet get-volume and then walking through it via foreach, but that cmdlet does not exist in Windows Server 2008. :(
Does anybody know an alternative?
I just need the drive letter, objectId/guid, free space, total space, and the name of each volume.
The WMI class Win32_Volume has the information you are looking for
Get-WMIObject -Class Win32_Volume | Select DriveLetter,FreeSpace,Capacity,DeviceID,Label
Which a little fancy footwork you can make the drive space properties looking a little more appealing.
Get-WmiObject -Class Win32_Volume |
Select DriveLetter,
#{Label="FreeSpace (In GB)";Expression={$_.Freespace/1gb}},
#{Label="Capacity (In GB)";Expression={$_.Capacity/1gb}},
DeviceID,Label |
Format-Table -AutoSize
Get-Volume is only in Powershell 4.
You can do this tho:
Get-WmiObject Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace, VolumeName

Resources