Modifying the object result in PowerShell [duplicate] - powershell

This question already has an answer here:
Pull NT user ID from powershell
(1 answer)
Closed 3 years ago.
I'm new to PowerShell and it would be much appreciated if I could get some expertise assistance with a script that I'm trying to write in PowerShell.
Objective:
Run a script to remotely check the name of the current user who is logged on to that machine.
Current script:
This line with the variable of $EnterComputerName prompts us to input in what computer name we want to search.
$EnterComputerName = Read-Host -Prompt "Enter Computer name"
This line searches the details from that specified computer and pipe it so that it will only show the Username property.
$Name = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $EnterComputerName | Select-Object Username
Problem:
The result of the above line only outputs the user ID instead of their actual name, example: domain\N12345
I want to use the following line to convert userID into name:
Get-ADUser $Name | Select-Object GivenName, Surname
However, Get-ADUser only recognizes 'N23705' instead of 'domain\N23705'. Is there a way I can shorten this to 'N23705' and pass that value to the $Name variable?

One simple way to accomplish this is to use replace to remove the unwanted domain prefix.
$Name = (Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $EnterComputerName).UserName -replace ".*\\", ""
Edit: removed Parenthesis in replace syntax

Related

How do I search in Powershell

I have two commands that aim to search for the Input Hostname:
$Hostname = Read-Host -Prompt "Which HOSTNAME do you want to search for?"
Get-ADComputer -Filter {Name -like $Hostname* } -Server {domain.org} | Sort-Object
How do I make this work? I want to make it interchangably so that I can put in the name I want to search and it executes it for me but I want to search all Hostname that start with $Hostname not just $Hostname thats why I put the * there but that doesnt seem to work. Does anyone have a suggestion?

Clusterparameter ObjectGUID shifted

So I try to link the networkname of a cluster resource to the AD object by the objectGUID in powershell.
If I execute following command Get-ClusterResource -Cluster CLxxx -Name NameOfResource the NetworkName object is returned.
I can ask for the clusterparameters and the parameter ObjectGUID (Get-ClusterResource -Cluster CLxxx -Name NameOfResource | Get-ClusterParameter -Name objectguid).Value
It will return something like 5efa2b5674c75d43bcdad1c2c183d5ca
So far so good.
If I try to get the ADobject from Active Directory (Get-ADComputer -Filter {Name -Like "$Name"}).ObjectGUID.guid
It will return something like 562bfa5e-c774-435d-bcda-d1c2c183d5ca
It is almost the same but not quite.
Al the characters are there but not in the correct order.
ClusterParameter: 5efa2b5674c75d43bcdad1c2c183d5ca
Active Directory: 562bfa5e-c774-435d-bcda-d1c2c183d5ca
If you look at the string AD returned you can split the string in 5 sequences on the -.
The last 2 are in the correct order but the first three have to switch front to back (2 characters at a time).
ClusterParameter: 5efa2b56-74c7-5d43-bcda-d1c2c183d5ca
Active Directory: 562bfa5e-c774-435d-bcda-d1c2c183d5ca
It is the same on 2008,2012 and 2016.
Does someone have an explanation for this?

How do I know what to pass in as TargetDevice, for Powershell DeviceManagement -> Enable-Device

I installed the DeviceManagement module for Powershell, specifically for the purpose of its Enable-Device and Disable-Device functions.
But when I call either of those, it needs a TargetDevice(which makes sense, obviously).. but I can't figure out the "name" of my device(a drive in this case) for the purposes of this command.
As with most PowerShell cmdlets, they are designed with the pipeline in mind.
Typically the best way to handle this is to first Get the target of your Set or Update cmdlet, and pipe it into the one that changes it:
$deviceName = Read-Host -Prompt 'Please enter the Name of the Device to Disable'
Get-Device | Where-Object -Property Name -Like $deviceName | Disable-Device
$deviceName = Read-Host -Prompt 'Please enter the Name of the Device to Enable'
Get-Device | Where-Object -Property Name -Like $deviceName | Enable-Device
This is taken directly from Device Management PowerShell Cmdlets Sample – An introduction.

Get-WMIObject include computer name

I'm trying out a script to go grab installed software on servers remotely. Problem is I want it to output certain attribs including the computer name but I can't seem to figure out how to get the name inserted.
Here is what I have so far...
$servers = Get-QADComputer -SearchRoot "OU=servers,OU=mydomain:-),DC=COM" | Select Name
...which works fine of course. Then...
$servers | % {Get-WMIObject -Class Win32Reg_AddREmovePrograms} | select Displayname,Version,InstallDate,PSComputerName
... which provides the full list of software installed on all servers in that OU but the PSComputerName becomes MY COMPUTER (the computer I run the query from - not the computername of the system being queried). The goal is to have the servername the software is installed on on each line item of software. I've asked professor Google and don't seem to see anything helpful (or anything that I understand anyway).
Hope this makes sense. semi-amateur PS script writer so hopefully this is easy for you guys. Thanks in advance for your help
Your command:
Get-WMIObject -Class Win32Reg_AddREmovePrograms
Does not specify computer to query, so it just query computer command being executed on. Thus PSComputerName display MY COMPUTER, as MY COMPUTER is computer being queried. You have to specify -ComputerName parameter to Get-WMIObject cmdlet to query specific computer. And -ComputerName parameter accept array of computer names, so you can put array of computer names to it instead of using ForEach-Object cmdlet and query one computer at time.
Since the object returned from the WMI call doesn't contain the computer you made the request on, you need to include it yourself from include your ForEach-Object (%) block. You could use Add-Member to add it yourself, then do your Select-Object outside like you're doing now:
$servers | % {
Get-WMIObject -Class Win32Reg_AddREmovePrograms -ComputerName $_ |
Add-Member -MemberType NoteProperty -Name ComputerName -Value $_ -PassThru
} | select Displayname,Version,InstallDate,ComputerName
Another way is to move the Select-Object to inside the block and do it within there, by creating a new property on the fly with a hashtable:
$servers | % {
Get-WMIObject -Class Win32Reg_AddREmovePrograms -computername $_ |
Select-Object Displayname,Version,InstallDate,#{Name='ComputerName';Expression={$_}}
}

Formatting issues / missing data when multiple commands use Select-Object within a script

I've run into a problem with my PowerShell scripts where I am "losing" output that was going to the console, or being redirected. After much legwork, I simplified it down to an easily documented example of the problem.
Place the following single line in a script (test1.ps1), and invoke it from a basic PowerShell command window:
Get-WmiObject win32_share | select name, path
and you will likely get two columns of output similar to the following:
PS C:\Users\me\temp> ./test1.ps1
name path
---- ----
ADMIN$ C:\Windows
C$ C:\
IPC$
Users C:\Users
but now, create a two line script (test2.ps1) like this, and run it in the same manner:
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path
and observe the output gets mangled:
PS C:\Users\me\temp> ./test2.ps1
name
----
ADMIN$
C$
IPC$
Users
ADMIN$
C$
IPC$
Users
The two commands are actually run , but the second call gets "squeezed" into the output of the first. It lost its second column, and its header and spacing.
This really seems to be a problem of the "first" output not properly "closing out", because it really doesn't seem to matter what the second line is if it pipes into another select statement.
As an aside, my original lines looked a bit more like this:
Get-WmiObject win32_share | select name, path | Write-Output
Get-WmiObject win32_share | select name | Write-Output
So that from a powershell prompt, I could direct the output wherever I desired using redirection
PS C:\Users\me\temp\> ./test2.ps1 > ./outfile.txt
As stated, actual case is more complez than this, but at this point, I just want to get a understanding of what is happening.
Bug? Or failure to comprehend on my part?
The link from mjolinor explains it in more detail but PowerShell is trying to group your outputs together here. An important line from the post states:
If the first Object has 2 properties, you'll get a 2 column table even if all the other objects in the stream have 10 properties.
In the following example
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path
When the seconds command has run the output from the previous did not have that property so PowerShell, more specifically Out-Default drops it in output in order to make all the output synchronous.
I would be more curious what your real code was that was creating this issue. Like expirat001 shows you can convert the output to string and this won't happen since they are no longer objects. Be careful doing so as you can lose the original objects this way. Either way the data is not lost. Just not being displayed the way you expect.
Referring back to the example from before we can pretend the first line didn't have a path property. Calling it from select anyway would just create the null column but would allow the other output to be displayed.
# In this next command "path" is not a valid property but PowerShell will create the column anyway
Get-WmiObject win32_share | select name, path
Get-WmiObject win32_share | select name, path
This is cheating but you could sent one of the commands to a different output stream.
Get-WmiObject win32_share | select name
Get-WmiObject win32_share | select name, path | Out-Host
Get-WmiObject win32_share | select name | ft
Get-WmiObject win32_share | select name, path | ft
Get-WmiObject win32_share | ft name
Get-WmiObject win32_share | ft name, path
The link from mjolinor indeed explains a lot, the main issue here is that you are launching a script via & ./test2.ps1 and the output of this command is piped into Out-Default. In turn, Out-Default sees a set of PSObjects generated by Select-Object cmdlets, and examining the first object (this is the first object returned by Get-WmiObject win32_share | select name) it sees that it has only one property "name" and subsequently formats a table out of resultant objects gathering only name property out of all of them.
To circumvent, use ft or Format-Table cmdlet to turn the output of each line into a sequence of Strings and not PSObjects, this way when the script's output will be piped into Out-Default, it will pass strings through unprocessed.