Display all service names matching a string pattern - powershell

I'm trying to display the name (just the name) of all of the installed services that contain the string "SQL". For example, I want to see
SQLAgent$SQL2008_R2
SQLBrowser
SQLWriter
So I try this:
Get-WmiObject Win32_Service
This displays all of the services, but as a list.
Exit Code : 0
Name : ProtectedStorage
ProcessId : 664
StartMode : Manual
State : Running
Status : OK
Exit Code : 1077
Name : QWAVE
ProcessId : 0
StartMode : Manual
State : Stopped
Status : OK
(etc...)
This is good, but I just want to see the name. So I type:
Get-WmiObject Win32_Service | select-object Name
And I get what I expect:
sppuinotfy
SQLAgent$SQL2008_RT
SQLBrowser
SQLWriter
SSDPSRV
(etc ..)
All is good. I take the next step of filtering the names to only include SQL related ones:
Get-WmiObject Win32_Service | select-object Name | select-string -pattern 'SQL'
And now it's confusing. Here is my output:
#{Name=BcmSqlStartupSvc}
#{Name=MSOLAP$SQL2008_R2}
#{Name=MSSQL$SQL2008_R2}
(etc ...)
Why am I getting this output, instead of just the names?
What should I be typing to get just the names?

You can use Get-Service instead of get-WMIObject and do it like this"
get-service sql* | select -expand name

The easiest way to achieve that is using -Filter Parameter
Get-WMIObject Win32_Service -Filter "Name LIKE '%SQL%'" |
Select -ExpandProperty Name
In case, you want to go with your code only, here is the way you can modify it:
Get-WmiObject Win32_Service | Select-Object -ExpandProperty Name |
Select-String -pattern 'SQL'
Edit: LIKE operator takes a few meta characters to support matching pattern.
[] - for range matching. For example, Name LIKE '[a-f]%' will list all services starting with any letter from a to f.
^ - not. For example, Name LIKE '[^a-f]%' will list services that do not start with any letter from a to f.
_ - matches one letter. For example, Name LIKE 'S_L%' will list services that start with S and followed by any letter.

Get-Service | Where-Object {$_.Name -match "SQL"} |Select-Object Name

Related

PowerShell 5.1 using ExpandedProperty but not getting desired output

Given:
PowerShell 5.1
If I run the following:
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit*
I get this:
Status Name DisplayName
------ ---- -----------
Stopped BDESVC BitLocker Drive Encryption Service
Stopped Check Point Bit... Check Point Endpoint Security Bitlo...
But I want to expand both Name and DisplayName, so I do this:
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit* | Select -ExpandProperty Name
and get this:
BDESVC
Check Point Bitlocker Management
How do I get all the columns with column headers, like the first output above except without ellipses?
Status Name DisplayName
------ ---- -----------
Stopped BDESVC BitLocker Drive Encryption Service
Stopped Check Point Bit... Check Point Endpoint Security Bitlo...
Get-Service -DisplayName *wmi*
Status Name DisplayName
------ ---- -----------
Stopped wmiApSrv WMI Performance Adapter
Running WMIRegistrationSe… Intel(R) Management Engine WMI Provid…
I find myself using | Out-GridView if desired output isn't being shown.
Get-Service -DisplayName *wmi* |
Out-GridView
Out-GridView Result
Alternatively, you could use | Format-List if you're not set on using Table View
Get-Service -DisplayName *wmi* |
Format-List
Name : wmiApSrv
DisplayName : WMI Performance Adapter
Status : Stopped
DependentServices : {}
ServicesDependedOn : {}
CanPauseAndContinue : False
CanShutdown : False
CanStop : False
ServiceType : Win32OwnProcess
Name : WMIRegistrationService
DisplayName : Intel(R) Management Engine WMI Provider Registration
Status : Running
DependentServices : {}
ServicesDependedOn : {}
CanPauseAndContinue : False
CanShutdown : False
CanStop : True
ServiceType : Win32OwnProcess
If you only want Status,Name,DisplayName headers,
Get-Service -DisplayName *wmi* |
Select-Object -Property Status, Name, DisplayName |
Format-List
Status : Stopped
Name : wmiApSrv
DisplayName : WMI Performance Adapter
Status : Running
Name : WMIRegistrationService
DisplayName : Intel(R) Management Engine WMI Provider Registration
The ... are just a display problem (the data is there in full).
If you use Select-Object's -ExpandProperty parameter, you by definition only get property values, and since these values are strings in your case, that's all you get (albeit without truncation).
To prevent the for-display truncation, pipe to Format-Table -AutoSize, though note that this requires PowerShell to collect all output from the input command first, before starting to display output (see next section for alternatives).
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit* | Format-Table AutoSize
Note: Since the console (terminal) window width is always the limiting factor, -AutoSize can result in fewer columns getting displayed.
If possible, you can exclude columns that aren't of interest, by specifying only those that are, via -Property (you may omit this parameter name, becasue it is positionally implied); e.g.:
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit* |
Format-Table -Property Status, Name -AutoSize
Alternatives that avoid -AutoSize and its collect-everything-first behavior:
Use -Wrap, which doesn't truncate, but uses (artificial) line breaks to spread values that don't fit into the column across multiple lines.
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit* | Format-Table -Wrap
If you know the maximum width of a column of interest ahead of time, you can use a calculated property to prescribe a column's width; e.g.:
Get-Service -ComputerName WKSP000D1E3F -DisplayName *bit* |
Format-Table Status,
#{ Expression='Name'; Width=40 },
DisplayName

Get AD user properties from Active Directory

I am trying to filter the values of a property in Active Directory.
I tried:
Get-ADUser -filter * -Properties physicalDeliveryOfficeName | Where-Object (($_.physicalDeliveryOfficeName -like "NICE")) | Select-Object physicalDeliveryOfficeName, name
Get-ADUser -filter * -Properties physicalDeliveryOfficeName | Select-Object physicalDeliveryOfficeName, name | Where-Object (($_.physicalDeliveryOfficeName -like "NICE"))
I did not get any errors, but no results either.
I searched all users with physicaldeliverofficename is (myvalue). I would like to display name and office.
You have a syntax problem:
The Where-Object's (positionally implied) -FilterScript parameter expects a script block argument - { ... } - not a parenthesized expression ((...)).[1]
Therefore:
# Note the { ... } around the expression passed to Where-Object
Get-ADUser -Filter * -Properties physicalDeliveryOfficeName |
Where-Object { $_.physicalDeliveryOfficeName -eq "NICE" } # | ...
Note: Since "NICE" is a literal string rather than a wildcard pattern, I've used the -eq instead of the -like operator. If you doe need to find "NICE" as a substring, use something like -like "*NICE*" or, for case-sensitive matching, -clike "*NICE*", as Mathias R. Jessen suggests.
Note that you may alternatively use simplified syntax, which obviates the need for a script block and allows use of individual parameters (also note the absence of $_., which is implied):
Get-ADUser -Filter * -Properties physicalDeliveryOfficeName |
Where-Object physicalDeliveryOfficeName -eq "NICE" # | ...
Taking a step back:
Santiago Squarzon suggests performing the filtering at the source, by using Get-ADUser's -Filter or -LDAPFilter parameter, which is much more efficient; e.g.:
Get-ADUser -Filter 'physicalDeliveryOfficeName -eq "NICE"'
As an aside: There are many examples out there that use script-block syntax with -Filter (-Filter { ... }), but the -Filter parameter accepts a string and that string, even though it supports PowerShell-like syntax, is interpreted by the AD provider, so it's better to pass a string to begin with - see this answer for more information.
[1] If you use (...), the expression's value gets bound to the -Property parameter instead, and is therefore interpreted as a property name whose value - assuming such a property even exists - is interpreted as a Boolean that determines whether the input object at hand should be filtered in or not. If the expression doesn't evaluate to the name of a property that exists on an input object, $false is implied, and the input object is filtered out. In your case, this predictably resulted in no objects being filtered in and therefore no output.
The Select-Object cmdlet is used to select only the columns you want from a larger object or list.
For instance:
C:\git\Core> gsv Spooler | fl
Name : Spooler
DisplayName : Print Spooler
Status : Running
DependentServices : {Fax}
ServicesDependedOn : {RPCSS, http}
CanPauseAndContinue : False
CanShutdown : False
CanStop : True
ServiceType : Win32OwnProcess, InteractiveProcess
Get-Service returns Service Objects which have a lot of properties. If I only want certain ones, I'd use it like so:
C:\git\Core> gsv Spooler | Select Name,Status
Name : Spooler
Status : Running
You're using the cmdlet and probably discarding the columns which have the values you need. Run your one-liner again and remove the Select-Object cmdlet to see all of the columns availble, till you find the one that pertains to the Office.

Powershell select-string using -inputobject for HV replication

I'm trying to write a query of the replication status of our VMs. I would like to be more selective in what I'm looking for, however.
I can run this:
PS C:\Users\hc> Get-VMReplication -computername servername
and it'll return this:
Image 1
I'd like it to return the line in the list when there is a match, or nothing when there isn't. Ive so far gotten it to select an item from the list by writing it as this:
PS C:\Users\hc> ((Get-VMReplication -computername servername | select-string -inputobject {$_.Health} -pattern “Normal”) -like “Normal”)
but it unfortunately only displays a list of Normal:
Image 2
Ultimately I would like it it to list the column headings and the entire row if possible but I'm unsure as to where to go next. (note that I've used the "Normal" pattern just so it would create entries in this list. The final product will look for "Warning" and "Critical")
Don't use Select-String, use Where instead.
Get-VMReplication -computername servername | Where{ $_.Health -eq "Normal"}
Or later down the road it would look like:
Get-VMReplication -computername servername | Where{ $_.Health -eq "Warning" -or $_.Health -eq "Critical"}

Passing string in Get-ADUser filter parameter causes error - property not found in pscustomobject

I'm trying to create a new Active Directory user, but first I verify that the user doesn't exist already with Get-ADUser.
I import the user data from our HR department and build custom properties:
$newUsers = Import-Csv $csvFile |
Select-Object -Property #{n='EmpNum';e={$_.'Employee Number'}},
#{n='UPN';e={$_.'Email Address'}},
#{n='Alias';e={$_.'Email Address'.Split("#")[0]}} #### etc
When I loop through the objects from the CSV file, I use the UPN property to search for the user in Active Directory:
foreach ($newUser in $newUsers) {
$exists = Get-ADUser -Filter {UserPrincipalName -eq $newUser.UPN} -Properties * -Server $adServer -Credential $adCred
...
}
The filter causes an error:
Get-ADUser : Property: 'UPN' not found in object of type:
'System.Management.Automation.PSCustomObject'. At
C:\Users\bphillips.NEWHOPEOFIN\Dropbox\Powershell\NewHire\AddNewDSP.ps1:50
char:15
+ $exists = Get-ADUser -Filter {UserPrincipalName -eq $newUser.UPN} -Propertie ...
I've tried doing this: -Filter {UserPrincipalName -eq $("$newUser.UPN") but that doesn't help; I get another error
Get-ADUser : Cannot process argument because the value of argument
"path" is not valid. Change the value of the "path" argument and run
the operation again. At
C:\Users\bphillips.NEWHOPEOFIN\Dropbox\Powershell\NewHire\AddNewDSP.ps1:50
char:15
+ $exists = Get-ADUser -Filter {UserPrincipalName -eq $("$newUser.UPN")} -Prop ...
$newUser is a string, so I don't understand why it causes a problem. Hard-coding a UserPrincipalName like, "test#ourcompany.com" works, but the $newUser.UPN won't work.**
PS C:\> $newUser.UPN.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
and
PS C:\> $newUser.UPN | gm
TypeName: System.String
$newUser.UPN contains a valid string value
PS C:\> $newUser.UPN
ypope#ourcompany.net
What do I have to do to get $newUser.UPN to be recognized as a string for the filter parameter? What's going on that I don't understand?
The BNF for filter query strings does not allow expressions as the second operand in a comparison, only values (emphasis mine):
Syntax:
The following syntax uses Backus-Naur form to show how to use the PowerShell Expression Language for this parameter.
<filter> ::= "{" <FilterComponentList> "}"
<FilterComponentList> ::= <FilterComponent> | <FilterComponent> <JoinOperator> <FilterComponent> | <NotOperator> <FilterComponent>
<FilterComponent> ::= <attr> <FilterOperator> <value> | "(" <FilterComponent> ")"
<FilterOperator> ::= "-eq" | "-le" | "-ge" | "-ne" | "-lt" | "-gt"| "-approx" | "-bor" | "-band" | "-recursivematch" | "-like" | "-notlike"
<JoinOperator> ::= "-and" | "-or"
<NotOperator> ::= "-not"
<attr> ::= <PropertyName> | <LDAPDisplayName of the attribute>
<value>::= <compare this value with an <attr> by using the specified <FilterOperator>>
Put the value of the property you want to compare against in a variable and use that variable in the comparison. You may also want to define the filter as an actual string, if only for clarity (despite what it looks like the filter is not a scriptblock).
$upn = $newUser.UPN
$exists = Get-ADUser -Filter "UserPrincipalName -eq '$upn'" ...
Expressions can inside the filter block of a Get-ADUser but they need to be properly wrapped with quotes.
Get-ADUser -Filter "UserPrincipalName -eq '$($newUser.UPN)'"
Never use a script block ({ ... }) as the -Filter argument - the -Filter parameter's type is [string] - construct your filter as a string.
BenH's answer shows how to do that.
While seemingly convenient, using a script block only works in very limited scenarios and causes confusion when it doesn't work - such as when involving property access, as in this case.
For more information, see this answer of mine.

powershell how to remove `{}#` from output. Is there a special command to do it?

I entered gwmi win32_product | select -property name | select -first 1 and output to a file. My result was #{name=Google Talk Plugin}.
How can I get rid of #{}, and name. I only want it to show Google Talk Plugin?
#{} means your exporting an object with properties. Try the -ExpandProperty parameter in Select-Object. You could also combine both select-object commands, like:
gwmi win32_product | select -expandproperty name -first 1
I ran into a problem similar with
$drive = Get-WmiObject Win32_LogicalDisk -ComputerName $servername | Select-Object DeviceID
$drive comes up as #{DeviceID=C:}, #{DeviceID=D:}, ...
Here is my brute force hack at it.
The second Trim statement was because for some reason if I put it in the first Trim it starts to Trim the letters in the Drive =D: becomes :
enter code here
$Asdrive = #() #declared before to get rid of null pointer issue, also to tell PS this is an array not a string
#Write-Host "Trimming for Get-WmiObject"
for($i=0;$i -lt $drive.length; $i++) {
[string]$sdrive = $drive[$i]
[string]$sdrive1 = $sdrive.Trim("#","{","}","D","e","v","i","c","e","I","D")
[string]$sdrive2 = $sdrive1.Trim("=")
$Asdrive += $sdrive2
}
If you're running at least Version 3, you can also use the member enumeration feature and then array slicing to take the first one, instead of using select:
(gwmi win32_product).name[0]
I add some code as I found this question with google.
Frode F. solution is the best one.
If you write out something like:
Get-ADComputer -Filter * -SearchBase $OU | Select-Object Name
you get a proper List of all Computers in an OU. You can also pipe that to a CVS/HTML file and its still nice.
| Export-CSV "mylist.csv"
But if you store it into a variable (array) every name will be wrapped in #{}.
In my case I needed computer names in a variable. Here is the solution thanks to Frodo:
$computerList = Get-ADComputer -Filter * -SearchBase $OU | Select-Object -ExpandProperty Name
Hope it helps someone.
(would add it as comment under the right solution, but I don't have enough reputation to do so)