Filtering a Get-printer variable output - powershell

I need to get all the printers named with a printer name starting with P0
I'm new to PowerShell and the command get-printer did not support my syntax for the filtering. My output variable is empty.
I have tried filtering the command results and tried filtering the content of the results variable with all printers without success.
$PrinterList = Get-Printer -ComputerName "PrintServer" -Filter {name -like 'P0'}
Or
$PrinterList = Get-Printer -ComputerName "PrintServer"
$PrinterSort = $PrinterList.Name | Where-Object {$PrinterList.Name -Like "P0"}

Per the other answer, you need to include one or more wildcard characters in your string (e.g * for 0 or more characters, or ? for a single character).
You can also simplify your code to use a wildcard in the -Name parameter on the cmdlet directly:
$PrinterList = Get-Printer -ComputerName "PrintServer" -Name "P0*"

You need a wildcard for your -like, e.g. name -like 'P0*'
This should work with both of your solutions.

Related

Piping parameters into cmdlet

This was done for testing and we have the solution but I would like to dig deeper.
I have a file list.txt that contains names of computers:
name
computer1
computer2
computer3
...
when I try
Import-Csv .\list.txt | Select-Object -property #{n="computername";e={$_.name}} | Get-Service
we get an error "Get-Service : Cannot find any service with service name '#{computername=computer1}'." Which I understand as Get-Service trying to map computername=computer1 to the parameter "name" (name="computername=computer1") even though the parameter "computername" is specified.
My solution was to add the "name" parameter and it works as expected
Import-Csv .\list.txt | Select-Object -property #{n="computername";e={$_.name}} | Get-Service -name *
My question is, why? Get-Service should accept pipeline input byPropertyName and it recognizes computername. Why doesn't it bind it unless I specify another parameter? Neither "name", nor "computername" is required. Also
Get-Service
and
Get-Service -computername "computer1"
both work without specifying "name".

PowerShell - Pass array as an optional parameter value

I'm pretty new to PowerShell.
I'm trying to pass an array of server names as an optional parameter value to get the last bootup time for a list of servers.
Example 1
$serverList = #('server1"', '"server2"', '"server3"', '"server4"', '"server5"')
Get-CimInstance -ComputerName $serverList -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
Example 2
Get-CimInstance -ComputerName server1,server2,server3,server4,server5 -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
In example 1, I get an error that says it can't connect to the
servers.
In example 2, it works.
I'm likely missing a key piece of fundamental knowledge as to why what I'm doing wasn't working. What am I missing?
Thanks for the help.
In the first example you are over-doing things with the quotes. (also server1 has an ending double quote, but no starting double quote..)
By putting the servers inside single quotes ', the text inside it is taken literally, so you are feeding the cmdlet with names like "server2", so including the double-qoute characters.
These quotes obviously don't belong to the server name.
BTW: Not an error, but you don't need the #() when creating the server names array.
This would be a better way of setting up your string array, where you can use either single or double quote characters, but not both:
$serverList = 'server1', 'server2', 'server3', 'server4', 'server5'
Get-CimInstance -ComputerName $serverList -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
You have also noticed that when used as parameters to a cmdlet, you don't even need the quotes, and the elements are interpreted as strings, as long as they do not contain space characters:
Get-CimInstance -ComputerName server1,server2,server3,server4,server5 -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime

Removing #{} from the output [duplicate]

This question already has answers here:
How do I write the value of a single property of a object?
(2 answers)
Closed 2 years ago.
The output of the following code is like #{Average = 2}.How can I get the output as Average = 2, Without the #{}.
$cpu = $ENV:COMPUTERNAME |Foreach-Object {
Get-WmiObject -computername $_ win32_processor | Measure-Object -property LoadPercentage -Average | Select Average
}
Firstly, I don't think you need to pipe $env:COMPUTERNAME to Foreach-Object, since its of type System.String, not an array or any other type of collection. Would be easier to just use -ComputerName $env:COMPUTERNAME directly. You can see what the type is with ($env:COMPUTERNAME).GetType(). Also have a look at about_environment_variables for more information about Windows environment variables in PowerShell.
Secondly, as #Mathias R. Jessen suggested in the comments, you should use -ExpandProperty to expand the property #{Average = 2} to 2.
Modified command
Get-WmiObject -ComputerName $env:COMPUTERNAME -Class Win32_Processor `
| Measure-Object -Property LoadPercentage -Average `
| Select-Object -ExpandProperty Average
You could also run Get-Help Select-Object -Parameter ExpandProperty to see what ExpandProperty does for Select-Object.
-ExpandProperty <String>
Specifies a property to select, and indicates that an attempt should be made to expand that property. Wildcards are permitted in the property name.
For example, if the specified property is an array, each value of the array is included in the output. If the property contains an object, the properties of that object are displayed in the output.
Required? false
Position? named
Default value None
Accept pipeline input? False
Accept wildcard characters? false
Also as a side note mentioned in the comments by #mklement0, WMI cmdlets(e.g. Get-WmiObject) have been superseded by CIM cmdlets(e.g. Get-CimInstance) in PowerShell v3 (released in September 2012).. This is also pointed out to you when you run Get-Help Get-WmiObject:
Starting in Windows PowerShell 3.0, this cmdlet has been superseded by Get-CimInstance
And also in this Use CIM cmdlets not WMI cmdlets article. Another reason is that the future is PowerShell Core, which doesn't support WMI cmdlets anymore. You can have a look at this answer for more information.
With all that said, here is the equivalent CIM command using Get-CimInstance.
Get-CimInstance -ClassName Win32_Processor `
| Measure-Object -Property LoadPercentage -Average `
| Select-Object -ExpandProperty Average
Which will work on both Windows PowerShell and PowerShell Core.

Using Wildcard with WMIC Version Query

I am an InfoSec admin with an okay amount of PowerShell experience. I'll keep it short and sweet:
([WMI] "\\$comp\root\CIMV2:CIM_DataFile.Name='$path'").Version)
I use this for calling file versions instead of using get-item VersionInfo.ProductVersion, since this does not always return an accurate value. It works well. However, when $path is equal to something like this:
C:\Windows\System32\Macromed\Flash\Flash*.ocx
The query doesn't work because the file is not found. I imagine this is due to the single quotes around the variable ignoring the wildcard.
I will admit that I did find a work around to my problem here (the answer posted by JPBlanc):
Powershell get-item VersionInfo.ProductVersion incorrect / different than WMI
However, I want to know if it is possible for me to use a wildcard with my existing script.
You can't pass a wildcard directly, but you can query the filesystem with that wildcard and then loop through the results. In both cases here, I'm assuming that you're doing this remotely.
$FlashFiles = invoke-command -computername $comp {Get-ChildItem C:\Windows\System32\Macromed\Flash\Flash*.ocx;};
foreach ($File in $FlashFiles) {
write-output "$($File.Fullname): $(([WMI] "\\$comp\root\CIMV2:CIM_DataFile.Name='$($File.FullName)'").Version)"
}
Or do it with a single pipeline:
invoke-command -computername $comp {Get-ChildItem C:\Windows\System32\Macromed\Flash\Flash*.ocx||foreach-object {write-output "$($_.Fullname): $(([WMI] "\\$comp\root\CIMV2:CIM_DataFile.Name='$($_.FullName)'").Version)"};
You can make the latter even faster by running the WMI query local to the remote computer (you could do it with the first too, but it's not as pretty)
invoke-command -computername $comp {Get-ChildItem C:\Windows\System32\Macromed\Flash\Flash*.ocx|foreach-object {write-output "$($_.Fullname): $(([WMI] "\\.\root\CIMV2:CIM_DataFile.Name='$($_.FullName)'").Version)"}};
The Name property of a CIM_DataFile can't contain wildcards. I don't believe any of them can.
However, you can specify the Drive, Path, and Extension to get a list:
Get-WmiObject -ComputerName $comp -Class CIM_DataFile -Filter "Drive='C:' AND Path='\\Windows\\System32\\Macromed\\Flash\\' AND Extension='ocx'"
The syntax of Path is a bit flaky. You need the trailing backslashes, for example.
You can also pipe to Where-Object for further filtering:
Get-WmiObject -ComputerName $comp -Class CIM_DataFile -Filter "Drive='C:' AND Path='\\Windows\\System32\\Macromed\\Flash\\' AND Extension='ocx'" |`
Where-Object { $_.FileName -like 'Flash*' } |`
ForEach-Object { $_.Name; $_.Version }

Filter services when calling Get-Service

I did this in the past, and can't remember the correct command (I think I was using instring or soemthign?)
I want to list all the windows services running that have the word 'sql' in them.
Listing all the windows services is:
Get-Service
Is there a instring function that does this?
Get-Service -Name *sql*
A longer alternative would be:
Get-Service | where-object {$_.name -like '*sql*'}
Many cmdlets offer built in filtering and support wildcards. If you check the help files (Get-Help Get-Service -full), you will see
-name <string[]>
Specifies the service names of services to be retrieved. Wildcards are
permitted. By default, Get-Service gets all of the services on the comp
uter.
Required? false
Position? 1
Default value *
Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? true
Usually if filtering is built in to the cmdlet, that is the preferred way to go, since it is often faster and more efficient.
In this case, there might not be too much of a performance benefit, but in V2, where you could be pulling services from a remote computer and filtering there would be the preferred method (less data to send back to the calling computer).
You can get all the services that are running and having words sql.
Get-Service | Where-Object {$_.Status -eq "Running"} | Where-Object {$_.Name -like "*sql*"}
If you want more information, see this (not much difference)
http://nisanthkv.blog.com/2012/06/29/get-services-using-powershell
Hope it helps...
Please enter below command:
Get-Service -Name '*<search string>*'
Above answers are great, but this is more useful:
Get-WmiObject -ComputerName <INSERT COMPUTER NAME> -Class Win32_Service | where-object {$_.name -like '*sql*'}
It allows for this query on remote computers.
The Search String might be in either Display Name or Service Name (e.g. searching Service Name for "*SQL*" does not include the SQL Integration Services ...) so I filter both:
get-service | Where-Object {$_.DisplayName -like "*MySearchString*" -or $_.ServiceName -like "*MySearchString*"}