Get serialnumber from asset list - powershell

Started in recent weeks in a Junior infrastructure role, and begun playing around with powershell to help save some time here and there.
I am trying to do the following:
1- I'm port a CSV file with a single column names asset
2- Perform a "ForEach" check on each line to find the device's serial number
3- Output results to a CSV with two column "asset" and "serialnumber"
I have dabbled in a few areas, and am currently sitting at something like this:
$file1 = Import-Csv -path "c:\temp\assets.csv" | ForEach-Object {
$asset = $_.asset
}
wmic /node:$asset bios get serialnumber
Export-Csv -Path "c:\temp\assetandserial.csv" -NoTypeInformation
As you may or may not see, I tried to set the column labelled "asset" as the variable, however, not sure if I placed it correctly.
I have tried a few other things, but honestly it's all new to me, so I haven't the foggiest idea where to go from here.

wmic is deprecated, and, for rich type support (OO processing), using PowerShell-native cmdlets is preferable in general.
wmic's immediate PowerShell counterpart is Get-WmiObject, which, however, is equally deprecated, in favor of Get-CimInstance.
Important: The command below uses Get-CimInstance, but note that the CIM cmdlets use a different remoting protocol than the obsolete WMI cmdlets. In short: To use the CIM cmdlets with remote computers, those computers must be set up in the same way that PowerShell remoting requires - see this answer for details.
Get-CimInstance Win32_BIOS -ComputerName (Import-Csv c:\temp\assets.csv).asset |
Select-Object #{ n='Asset'; e='PSComputerName' }, SerialNumber |
Sort-Object Asset |
Export-Csv c:\temp\assetandserial.csv -NoTypeInformation
Note the use of member-access enumeration to extract all .asset values directly from the collection of objects returned from Import-Csv.
All computer (asset) names are passed at once to Get-CimInstance, which queries them in parallel. Since the ordering of the responses from the targeted remote machines isn't guaranteed, Sort-Object is used to sort the results.
A calculated property is used with Select-Object to rename the automatically added .PSComputerName property to Asset.

Related

Gathering System Process IO details

I am trying to prepare a report wherein I need to collect the I/O read,write and other bytes of all the process running on the system. Below is the script which I currently use.
Get-Process|select name,cpu,#{name="WorkingSet";Expression={$_.WorkingSet/1kb}},BasePriority,path|where {$_.Name -in 'dllhost','firefox','dsapi'}
Below is output that we obtain after a few processing and measure object.
The issue which I am facing is that for most of the system processes or where the username is system, the value for those returns mostly in the form zero. Kindly provide some directions on how to fix this issue and obtain the actual value for the system process as well.
<>
From what I read on the I/O values will not be extracted from the get-process cmdlet which is why I have used the below cmdlet and it works fine for user created process however for the system created process the script returns a zero value as show in the above image.
$gc = get-counter '\Process(dllhost)\IO Read Bytes/sec'
$gc.countersamples | sort cookedvalue
Ensure you're running powershell as administrator.
There is no ReadByteSec or WriteBytpeSec from what I can see.
You're also using a select statement which doesn't contain those properties.
Type this to see all the available properties for dllhost:
$processes = Get-Process | where {$_.Name -in 'dllhost'}
Get-Member -InputObject $processes[0]
And then add those to your statement:
Get-Process|select name,cpu,#{name="WorkingSet";Expression={$.WorkingSet/1kb}},BasePriority,path, *BytesField1, BytesField2, etc* |where {$.Name -in 'dllhost','firefox','dsapi'}

Problem with declaration of variables in powershell

I have declared 2 PowerShell variables
$prm=Get-WmiObject Win32_Product -Computer . -Filter "vendor = 'Wolters Kluwer Financial Services'" | Select-Object Name, Vendor, Version
$rgteng=Get-WmiObject Win32_Product -Computer . -Filter "vendor = 'WKFS'" | Select-Object Name, Vendor, Version
I want the output of this variable to a text file o/p #{Name=Wolters Kluwer Financial Services Regulatory Reporting FRA Param 11.2.0; Vendor=Wolters Kluwer Financial Services; Version=11.2.0}, I want this o/p to a text file.
I have tried using Write-Output and Write-Host, but none of them gives right o/p
What happens there looks like this (just the big picture):
Get-WmiObject Win32_Product -Computer . -Filter "vendor = 'Wolters Kluwer Financial Services'" creates an WMI object and pipes it to the next command
Select-Object Name, Vendor, Version transforms that object into a new PSCustom type object (more like a table version of your WMI object wtih only the desired information)
Then it gets messy :
if you use write-host or display it on the screen , the output will be formatted according the the powershell's settings (those settings can be changed by altering xml files)
if you use export-csv you basically use a convertto-csv | out-file c:\sometheing.txt + some formatting rules that are applied. (I think the UTF-8 type of the file is changed but I am not sure...)
So if you want to know exactly how your variable / file will look like, without having powershell formatting interfering with your work, use convertto-csv | out-file.

Why does "Get-Vm | Sls PoweredOff" not grep for VMs that are Powered off?

I am trying to use PowerCLI to search for a list of PoweredOff VMs.
I want to search the results of the command Get-Vm:
Vm01 PoweredOn 1 16
Vm02 PoweredOff 1 16
etc.
I want to search this list for "PoweredOff", but the PowerShell Sls doesn't seem to work if I type:
Get-Vm | sls PoweredOff
It will not show the PoweredOff virtual machines. Can anyone provide any guidance on outputting this a stream of text to search (rather then a list of Objects to search)?
PowerShell cmdlets return objects, not simple text output. You filter output by the values of specific properties with the Where-Object cmdlet.
Get-Vm | Where-Object { $_.PowerState -eq 'PoweredOff' }
Tabular or list output will normally show you the property names. However, not all of the objects' properties may be displayed by default, and sometimes the default output format of a particular type is made to look differently than the output would normally do (e.g. Get-Process output). You can get a list of all properties (and methods) of an object by using the Get-Member cmdlet. Add the parameter -Force to include intrinsic properties. Add the parameter -Static to show class methods instead of object methods.
For VMware's cmdlets you could also check the PowerCLI documentation, which lists the return types of the cmdlets.

Most optimal way of retrieving a property in Powershell

I'm just wondering, what is the optimal, fastest way of retrieving a property in powershell?
I'm using the (). right now to identify a remote computer's architecture (x86 or x64):
$arch = (Get-WmiObject –ComputerName XXXXX –Class Win32_OperatingSystem).osarchitecture
sometimes on a very very slow link, the command takes a while to resolve. For this reason, is there a faster way of retrieving a property than the (). method? I know there are different methods, for example:
... | Select-Object -expandproperty osarchitecture
Any suggestion as to which is better amongst all the possibilites? Thank you
Comment from TheIncorrigible1 chosen as answer:
No, there is not a "faster" way to retrieve a powershell object's
property. What is slow is your RPC connection to the PC. As far as the
most supported option? Select-Object -ExpandProperty since the ().
syntax doesn't work on collections before v3 – TheIncorrigible1

How Does Member Enumeration Work in PowerShell 3?

In PoweShell 2 we did:
Get-ChildItem | ForEach-Object {$_.LastWriteTime} | Sort-Object
In Powershell 3 we do:
(Get-ChildItem).LastWriteTime | Sort-Object
But how does it work, i read this blog post on MSDN and they say that its faster because the foreach loop isnt running? So how does it enumerate the properties then ?
PowerShell is doing the hard work for us and it loops over the collection internally. I like to call this "implicit foreach". Assuming the member you specified is present on each object, if the member you specified is a property, you get back its value. If it's a method, it invokes the method on the each object.
In v2, to get all process names you had to take care of looping yourself:
Get-Process | Foreach-Object {$_.Name}
In v3, the equivalent would be:
(Get-Process).Name
Same applies to methods. To kill all processes with name starting with note*:
(Get-Process note*).Kill()
The blog says foreach-object cmdlet is not running. Now it is taken care of by the language engine and not a cmdlet, making it faster. How it EXACTLY works is internal implementation detail and I think that is not what you really want to know.