Get-Service *sql* | sort DisplayName | out-file c:/servicelist.txt
I have a one line PowerShell script to extract list of all services running on my local machine, now, in addition to displaying "Status", "Name" and "DisplayName" I also want to display "Path to executable"
I think you'll need to resort to WMI:
Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, State, PathName
Update
If you want to perform some manipulation on the selected data, you can use calculated properties as described here.
For example if you just wanted the text within quotes for the Pathname, you could split on double quotes and take the array item 1:
Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, #{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List
Get-CimInstance can also be used to achieve the same, see here for the difference between CIM and WMI.
Get-CimInstance win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, #{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List
Since Get-WmiObject have been deprecated in PowerShell Core, you can use
Get-CimInstance -ClassName win32_service | ?{$_.Name -match '^sql'} | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt
instead.
If you don't need to check against a regular expression you can also use the -Filter parameter:
Get-CimInstance -ClassName win32_service -Filter "Name like 'sql%'" | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt
A variant on the WMI Query that may be faster (I just had to do this for an SCCM Client)
$SQLService=(get-wmiobject -Query 'Select * from win32_service where Name like "*SQL*"') | Select-object Name, DisplayName, State, Pathname
The other trick is to trap for the multiple SQL results if you want the path names without the Double Quotes (so you can action upon them)
$SQLService | Select-Object Name, DisplayName, State, #{Name='PathName';Expression=$_.Pathname.replace('"','')}
The big advantage to using -query in the get-wmiobject (or get-ciminstance) is the speed of processing. The older example gets a full list and then filters, whilst the latter grabs a very direct list.
Just adding in two cents :)
Cheers all!
Sean
The Energized Tech
You can also use the Regular Expression pattern and dump the result to file.
Get-WmiObject win32_service | ?{$_.Name -match '^sql'} | select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt
I'm not comfortable with the accepted answer's use of Expression={$_.PathName.split('"')[1]}} because it doesn't handle the variants of quotes, spaces, and args that I see in the data.
Here's a clunky method that does.
function PathFromServicePathName($pathName) {
# input can have quotes, spaces, and args like any of these:
# C:\WINDOWS\system32\lsass.exe
# "C:\Program Files\Realtek\Audio\HDA\RtkAudioService64.exe"
# C:\WINDOWS\system32\svchost.exe -k netsvcs -p
# "C:\Program Files\Websense\Websense Endpoint\wepsvc.exe" -k ss
# if it starts with quote, return what's between first and second quotes
if ($pathName.StartsWith("`"")) {
$pathName = $pathName.Substring(1)
$index = $pathName.IndexOf("`"")
if ($index -gt -1) {
return $pathName.Substring(0, $index)
}
else {
# this should never happen... but whatever, return something
return $pathName
}
}
# else if it contains spaces, return what's before the first space
if ($pathName.Contains(" ")) {
$index = $pathName.IndexOf(" ")
return $pathName.Substring(0, $index)
}
# else it's a simple path
return $pathName
}
Get-WmiObject win32_service | select Name, DisplayName, #{Name="Path"; Expression={PathFromServicePathName $_.PathName}} | Format-List
A variant with Format-List with full path, results in file :
Get-WmiObject win32_service | Format-Table -Wrap -AutoSize -Property State,Name,PathName | out-file C:\servicelist.txt
Related
I am storing the following query value in a variable:
$unquotedPaths = Get-WmiObject -Class Win32_Service | Select-Object -Property Name,DisplayName,PathName,StartMode | Select-String "auto"
The problem starts when i print that variable becouse the variable takes from the query an object which is formed by hashtables like in this output:
PS C:\Users\pc> Get-WmiObject -Class Win32_Service | Select-Object -Property Name,DisplayName,PathName,StartMode | Select-String "auto"
#{Name=AGMService; DisplayName=Adobe Genuine Monitor Service; PathName="C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGMService.exe"; StartMode=Auto}
#{Name=AGSService; DisplayName=Adobe Genuine Software Integrity Service; PathName="C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGSService.exe"; StartMode=Auto}
#{Name=asComSvc; DisplayName=ASUS Com Service; PathName=C:\Program Files (x86)\ASUS\AXSP\1.01.02\atkexComSvc.exe; StartMode=Auto}
#{Name=AudioEndpointBuilder; DisplayName=Compilador de extremo de audio de Windows; PathName=C:\WINDOWS\System32\svchost.exe -k LocalSystemNetworkRestricted -p; StartMode=Auto}
How i can get and output like this:
Name DisplayName PathName Startmode
---------- ------------- ------------ ------------
ExampleName ExampleDisplayName C:\Example Auto
Select-String is meant to search and match patterns among strings and files, If you need to filter an object you can use Where-Object:
$unquotedPaths = Get-WmiObject -Class Win32_Service |
Where-Object StartMode -EQ Auto |
Select-Object -Property Name,DisplayName,PathName,StartMode
If the filtering required more complex logic you would need to change from Comparison Statement to Script Block, for example:
$unquotedPaths = Get-WmiObject -Class Win32_Service | Where-Object {
$_.StartMode -eq 'Auto' -and $_.State -eq 'Running'
} | Select-Object -Property Name,DisplayName,PathName,StartMode
I am attempting to use the -ExpandProperty feature in PowerShell to stop the header appearing in the output and format the date without minutes and seconds. This is just to get the created date for an AD Object:
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object -ExpandProperty #{Name="Created";Expression={$_.Created.ToString("yyyy-MM-dd")}}
This does not produce a result, only if I exclude the "-ExpandProperty" part will it produce the right date format BUT includes the header "Created" which I don't want.
Any ideas please?
I don't have access to an AD at the moment, but this could be what you are after
Updated
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | Select-Object Created | ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}
To complement LotPings' helpful answer, which offers effective solutions:
As for why your code didn't work:
While Select-Object's -Property parameter accepts hashtables that define calculated properties (such as in your code), the -ExpandProperty parameter only accepts a property name, as a string.
Therefore, your hashtable is simply stringified, resulting in string literal System.Collections.Hashtable, causing Select-Object to complain, given that there is no property by that name.
The purpose of -ExpandProperty is to output just a property value rather than a custom object with that property.
You therefore do not need a detour via Select-Object, and can just use the value-outputting script block - { $_.Created.ToString("yyyy-MM-dd") } - directly with ForEach-Object instead, as shown at the bottom of LotPings' answer.
However, there is an obscure feature that you forgo by using ForEach-Object: Select-Object allows combining -ExpandProperty with -Property, in which case the properties specified via -Property are added as NoteProperty members to the value of the property specified via -ExpandProperty:
PS> $val = [pscustomobject] #{ one = 'uno'; two = 2 } |
Select-Object -ExpandProperty one -Property two; $val; $val.two
uno
2
Note how the output string value, 'uno' has a copy of the input object's .two property attached to it.
To emulate that with ForEach requires more work:
PS> $val = [pscustomobject] #{ one = 'uno'; two = 2 } | ForEach-Object {
$_.one + '!' | Add-Member -PassThru two $_.two
}; $val; $val.two
uno!
2
In PowerShell there nearly always is more than one solution to a problem-
(Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object #{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} ).Created
or
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object #{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} |
Select-Object -Expand Created
Parameter names can be shorted as long as they are uniquely identifiable and there are also shortcuts (uppercase letters) so -EA is -ErrorAction
A calculated property does IMO make no sense here as it is the only output, so this should do also:
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}
I'm trying to extract the key for a user but I get unwanted spaces and newlines before the string and after it. My script is the following:
$File = gwmi Win32_UserProfile -co MADS000001 |
select localpath, sid |
Where-Object {$_.localpath -eq "C:\Users\Administrator"} |
select Sid |
ft -HideTableHeaders |
Out-String -Stream
Write-Host $file
How can I get rid of them?
The output looks like this:
I'm not sure of your goal.
If you want to find out the name of the local Administrator account (even if it's been renamed), you can write this:
Get-WmiObject Win32_UserAccount -Filter 'LocalAccount=TRUE AND SID LIKE "%-500"' |
Select-Object -ExpandProperty Name
If you want that user's profile path, you can combine them:
$adminSID = Get-WmiObject Win32_UserAccount -Filter 'LocalAccount=TRUE AND SID LIKE "%-500"' |
Select-Object -ExpandProperty SID
$profilePath = [WMI] "root\cimv2:Win32_UserProfile.SID='$adminSID'" |
Select-Object -ExpandProperty LocalPath
Note the use of Select-Object -ExpandProperty to select a specific property and output only that property.
I think you are over complicating it a bit.
If you just do
$profileInfo = Get-WmiObject Win32_UserProfile -ComputerName 'MADS000001' |
Where-Object {$_.localpath -like "*\Administrator"} |
Select-Object LocalPath, Sid, PSComputerName
You will get an object (if found of course, $null otherwise) with the three properties in the Select-Object command.
The $profileInfo.LocalPath you can use to delete the folder.
The $profileInfo.Sid string value you can use to remove the registry key for that user at
HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<SID>
P.s. The second 'unwanted' whitespace you have outlined is simply a newline Write-Host always adds unless you use Write-Host $profileInfo.Sid -NoNewline
To get the SID for a user:
$userName = "Administrator"
$sid = Get-WmiObject Win32_UserAccount -Filter "LocalAccount=TRUE AND Name='$username'" |
Select-Object -ExpandProperty SID
Note that this will fail if the user is not named Administrator.
Also - note the use of Select-Object -ExpandProperty to select the value of a specific property of an object.
I have a query that is listing all computers and their OS, and exporting it to a CSV file:
Get-ADComputer -Filter{OperatingSystem -NotLike "*server*"} -Properties * | select name,CanonicalName,OperatingSystem,OperatingSystemVersion | Export-Csv C:\Temp\AllComputersOS.csv -NoTypeInformation
I would like to also know the chassistype, and have this WMI query:
WmiObject win32_systemenclosure -computer $computer.Name | Select chassistypes
How can I combine these two commands and export the results to a single csv?
You could do this via a calculated property in the Select-Object:
Get-ADComputer -Filter {OperatingSystem -NotLike "*server*"} -Properties * | select name,CanonicalName,OperatingSystem,OperatingSystemVersion,#{N='ChassisType';E={(WmiObject win32_systemenclosure -ComputerName $_.Name).chassistypes}} | Export-Csv C:\Temp\AllComputersOS.csv -NoTypeInformation
Beware this will be fairly slow to execute.
The calculated property part is this:
#{N='ChassisType';E={(WmiObject win32_systemenclosure -ComputerName $_.Name).chassistypes}}
It uses a special hashtable construct where you provide the keys N (Name, although you can also use L for Label or either in full) and E (Expression) to, where the Expression is some scriptblock to execute. Within this we're using $_.Name to get the current computer name property from the pipeline variable.
I want to write a PowerShell script to get all the print servers in a network.
I have used the following LDAP query, but it returns only servers with network printers attached to it. But not other print servers that have a remote printer attached to it.
Here's the code I used to get the print servers (But getting only the servers with n/w printers)
Import-Module ActiveDirectory
[array]$testarray = Get-ADObject -LDAPFilter "(&(&(&(uncName=*)(objectCategory=printQueue))))" -properties *|Sort-Object -Unique -Property servername |select servername
$testarray
You could try something like Get-WMIObject win32_printer | select name,local wrapped in a foreach-object loop like this:
$servers | ForEach-Object {
Get-WMIObject Win32_Printer -computername $_ | Where-Object {$_.local -like 'False'} | select Name,local,SystemName | format-table -a
}
The $servers can be what scoped to whatever servers you need to check.
Use Get-WMIObject Win32_Printer | select * to see what properties you want to report back on and include them in the | select Name,local,SystemName section of the script
You could use a combination of Get-ADComputer and Get-Printer to list all shared printer queues on computers joined to your domain:
Get-ADComputer -Filter * | % {
$computer = $_.Name
Get-Printer -Computer $computer | ? { $_.Shared } | select -Expand Name
}
This doesn't cover computers that aren't domain members, though.