Command output from Variable showing spaces - powershell

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.

Related

I want to write a variable out but delete the top 3 lines

I am trying to write a powershell script to check all of the online computers and then make it one neat column Here is the code I have so far...
$computers = get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name
$computers1 = get-adcomputer -LDAPFilter "(Name=SDA005*)" | Select-Object -Property Name
$computers2 = get-adcomputer -LDAPFilter "(Name=SDA006*)" | Select-Object -Property Name
$computers3 = get-adcomputer -LDAPFilter "(Name=SDA007*)" | Select-Object -Property Name
$computers4 = ($computers) + ($computers1) + ($computers2) + ($computers3)
[array]$online = #($computers4.Name | % {test-connection -erroraction silentlycontinue -Count 1 $_})
$wIw = $online | Select-Object Address
$wIw
But the output always leaves the top 3 lines with extraneous data I don't want. i.e
Address
-------
SDA0003
SDA0007
SDA000B
SDA000C
SDA0050
SDA0051
SDA0054
SDA0057
SDA005F
SDA0061
SDA006B
SDA006D
SDA0076
I can write it to a text file and then pipe it to select-object -skip 3, but that does not seem to work with a variable.
thanks for any advice.
What you are seeing is the header (e.g. the "Address" property). To output it to the screen without the header, you can use the -HideTableHeaders in a Format-Table command:
...
$wIw = $online | Select-Object Address
$wIw | Format-Table -HideTableHeaders
Ohh yes, that treat is sometimes quit helpful but most of the time it is in the way. Here is how I get rid of it:
$computers = (get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name).name
Looks like what you want can be done easier like this:
$wIw = (Get-ADComputer -LDAPFilter "(Name=SDA00*)" |
Where-Object { ($_.Name | Test-Connection -Count 1 -Quiet -ErrorAction SilentlyContinue) }).Name

How to change an output formed by hashstables Powershell

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

PowerShell - Use a string in a foreach-object against the Description AD property of a computer object

I am trying to send a user name (SamAccountName) down the PowerShell Pipeline to find a computer based on the Description property in Active Directory:
The Description property is always "something-UserName"
I know I don't need to send the variable down the pipeline and can simply express it in the filter but I have s specific use case where I need to do this.
This is what I have tried:
"bloggsJ" | %{Get-ADComputer -server domain.com -Filter * -Properties Description | ?{$_.Description -eq "something-$_"}} | select Name
This produces nothing even though there is a computer with a description property of "Something-bloggsJ" on that domain.
Any advice please.
Instead of using the -eq operator, I would use -like.
Something like this:
"bloggsJ", "IanB" | ForEach-Object {
$name = $_
Get-ADComputer -Filter * -Properties Description |
Where-Object {$_.Description -like "*-$name"}
} | Select-Object Name
Inside the ForEach-Object loop, the $_ automatic variable is one of the usernames. Inside the Where-Object clause, this $_ variable represents one ADComputer object, so in order to have the username to create the -like string, you need to capture that name before entering the Where-Object clause.
I believe you are missing the underscore for $_ variable:
"ivan" | ForEach-Object -Process { Get-ADComputer -Filter * -properties description | Where-Object -Property description -eq "something-$_"}
this one is working ...

Export Get-ADComputer to CSV [duplicate]

This question already has answers here:
How to get an object's property's value by property name?
(6 answers)
Closed 5 years ago.
I am working on a script which takes Hostnames from a CSV, Files them against Get-ADComputer and then saves certain Objects in certain columns of the original CSV.
While the solution seems like a basic Task (code below), my problem is, that the Output of Get-ADComputer always (you can see I played around with Out-String but also tried other formatting options) contains a lot of NewLine characters or other formatting issues which make the CSV confusing.
Clear-Host
Import-Module ActiveDirectory
$import = Import-Csv 'XXX' -Delimiter ';'
Foreach ($row in $import){
$hostname = $row.HOSTNAME
if($hostname.length -gt 3){
$computer = Get-ADComputer -Filter {Name -like $hostname} -Properties LastLogonDate, LastLogonTimeStamp
$row.AD_LastLogon.ToString() = $computer | Select-Object LastLogonDate | Select-Object -first 1 | FT -HideTableHeaders | Out-String
$row.AD_LLTimestamp = $computer | Select LastLogonTimestamp |Select-Object -first 1 | FT -HideTableHeaders | Out-String
}
}
$import | Export-Csv 'XXX' -Delimiter ';' -NoType
My question now is, if anyone could help with a method to get the bare string result of for example Get-ADComputer's LastLogonDate, without any formatting or headers included.
Thanks in advance!
Use the -ExpandProperty parameter of Select-Object to extract just the parameter you want. You can only specify one parameter to exapand at a time.
$row.AD_LastLogon = $computer | Select-Object -ExpandProperty LastLogonDate -First 1 | Out-String
$row.AD_LLTimestamp = $computer | Select-Object -ExpandProperty LastLogonTimestamp -First 1
I don't believe the -First 1 should be necessary. Get-ADComputer shouldn't be finding multiple computers with the same name.
Also, you shouldn't need to retrieve both LastLogonDate and LastLogonTimestamp. The former is the same value as the latter, just converted to a DateTime from the irritating NT Time Epoch that LastLogonTimestamp uses. Have you got a system that requires both?
Finally, just a note but this:
$row.AD_LastLogon.ToString() = $computer | [...]
It doesn't make sense. You can't assign a value to a method. I would be surprised if that didn't error or otherwise do nothing at all.

How can I extract "Path to executable" of all services with PowerShell

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