conver powershell script to csv - powershell

im doing some testing with powershell to list hardware information of each computer in my domain. my script will get a list of computer from a text file that i created using powershell.
$arrComputers = get-Content -Path "C:\powershell\List.txt"
foreach ($strComputer in $arrComputers)
{
$colItemsOs = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsOs)
{
Write-host "Computer Name: " $strComputer
Write-host "OsName: " $objItem.Name
Write-host "Version: " $objItem.Version
}
$colItemsCompsys = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsCompsys)
{
Write-host "Memory: " $objItem.TotalPhysicalMemory
Write-host "Manufacturer: " $objItem.Manufacturer
Write-host "Model: " $objItem.Model
Write-host "Domain: " $objItem.Domain
}
$colItemsSysEnc = get-wmiobject -class "Win32_SystemEnclosure" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsSysEnc)
{
Write-host "SerialNumber: " $objItem.SerialNumber
}
$colItemsProcessor = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsProcessor)
{
Write-host "Processor: " $objItem.Name
}
$colItemsIP = get-wmiobject -class "Win32_NetworkAdapterConfiguration " -namespace "root\CIMV2" `
-computername $strComputer -Filter "IpEnabled = TRUE"
foreach ($objItem in $colItemsIP)
{
Write-host "IPAddress: " $objItem.IpAddress
}
Write-host | Out-File c:\powershell\reportbeta.csv
}
however, i am unable to do so. how do i produce the result in csv file which will be able to be uploaded to my database using sqlcmd later on.
what am i missing out?
thank you
ive managed to display output in text file. however, only 1 record is displayed.
$arrComputers = get-Content -Path "C:\powershell\List.txt"
foreach ($strComputer in $arrComputers)
{
$colItemsOs = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsOs)
{
$strComputer
$Name =$objItem.Name
$Version = $objItem.Version
}
$colItemsCompsys = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsCompsys)
{
$TotalMemory = $objItem.TotalPhysicalMemory
$Manufacturer = $objItem.Manufacturer
$Model = $objItem.Model
$Domain = $objItem.Domain
}
$colItemsSysEnc = get-wmiobject -class "Win32_SystemEnclosure" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsSysEnc)
{
$SerialNUmber = $objItem.SerialNumber
}
$colItemsProcessor = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" `
-computername $strComputer
foreach ($objItem in $colItemsProcessor)
{
$Processor = $objItem.Name
}
$colItemsIP = get-wmiobject -class "Win32_NetworkAdapterConfiguration " -namespace "root\CIMV2" `
-computername $strComputer -Filter "IpEnabled = TRUE"
foreach ($objItem in $colItemsIP)
{
$IPV4 = $objItem.IpAddress
}
$OutputObj = New-Object -Type PSObject
$OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $strComputer.ToUpper()
$OutputObj | Add-Member -MemberType NoteProperty -Name Name -Value $Name
$OutputObj | Add-Member -MemberType NoteProperty -Name Version -Value $Version
$OutputObj | Add-Member -MemberType NoteProperty -Name TotalPhysicalMemory -Value $TotalMemory
$OutputObj | Add-Member -MemberType NoteProperty -Name Manufacturer -Value $Manufacturer
$OutputObj | Add-Member -MemberType NoteProperty -Name Model -Value $Model
$OutputObj | Add-Member -MemberType NoteProperty -Name Processor -Value $ProcessorSpeed
$OutputObj | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $SerialNo
$OutputObj | Add-Member -MemberType NoteProperty -Name Domain -Value $Domain
$OutputObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPV4
$OutputObj | Export-CSV -NoTypeInformation "c:\powershell\report.txt"
}
im out of ideas now. should i make it into array like?
please advise.
Thank you

The problem is that you are exporting to csv within the loop, so the last item will be the only one showing. Try something like this.
Before the loop:
# Create empty array
$report = #()
At the end of the loop, in place of where you are currently exporting to CSV:
#Add item to report
$report += $OutputObj
Finally, after the end of the loop:
$report | Export-CSV -NoTypeInformation "c:\powershell\report.txt"

I suggest you assign the foreach result to a variable then pipe it to Export-Csv. It should perform faster and is much efficient than recreating, and updating, an array in each loop iteration.
$result = foreach($strComputer in $arrComputers)...
$result | Export-CSV ...
If you used the Foreach-Object' cmdlet to loop over computers you could skip the whole assignment or array creation, processing one object at a time (streamlined) and pipe directly toExport-CSV`:
Get-Content -Path C:\powershell\List.txt | Foreach-Object{
...
} | Export-Csv ...

Related

The term 'Win32_computerSystem' is not recognized as the name of a cmdlet

I'm fairly new to Powershell scripting and have been playing around with a script I found online which queries all the systems in my domain and outputs bits of hardware information in a CSV. The script:
$testcomputers = Get-Content -Path 'C:\scripts\computers.txt'
$exportLocation = 'C:\scripts\pcInventory.csv'
foreach ($computer in $testcomputers) {
if (Test-Connection -ComputerName $computer -Quiet -count 2){
Add-Content -value $computer -path c:\scripts\livePCs.txt
}else{
Add-Content -value $computer -path c:\scripts\deadPCs.txt
}
}
$computers = Get-Content -Path 'C:\scripts\livePCs.txt'
foreach ($computer in $computers) {
$Bios = Win32_computerSystem -Computername $Computer
$Sysbuild = Get-WmiObGet-WmiObject win32_bios -Computername $Computer
$Hardware = Get-WmiObjectject Win32_WmiSetting -Computername $Computer
$OS = Get-WmiObject Win32_OperatingSystem -Computername $Computer
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $Computer | Where-Object {$_.IPEnabled}
$driveSpace = Get-WmiObject win32_volume -computername $Computer -Filter 'drivetype = 3' |
Select-Object PScomputerName, driveletter, label, #{LABEL='GBfreespace';EXPRESSION={'{0:N2}' -f($_.freespace/1GB)} } |
Where-Object { $_.driveletter -match 'C:' }
$cpu = Get-WmiObject Win32_Processor -computername $computer
$username = Get-ChildItem "\\$computer\c$\Users" | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime -first 1
$totalMemory = [math]::round($Hardware.TotalPhysicalMemory/1024/1024/1024, 2)
$lastBoot = $OS.ConvertToDateTime($OS.LastBootUpTime)
$IPAddress = $Networks.IpAddress[0]
$MACAddress = $Networks.MACAddress
$systemBios = $Bios.serialnumber
$OutputObj = New-Object -Type PSObject
$OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
$OutputObj | Add-Member -MemberType NoteProperty -Name Manufacturer -Value $Hardware.Manufacturer
$OutputObj | Add-Member -MemberType NoteProperty -Name Model -Value $Hardware.Model
$OutputObj | Add-Member -MemberType NoteProperty -Name Processor_Type -Value $cpu.Name
$OutputObj | Add-Member -MemberType NoteProperty -Name System_Type -Value $Hardware.SystemType
$OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System -Value $OS.Caption
$OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_Version -Value $OS.version
$OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_BuildVersion -Value $SysBuild.BuildVersion
$OutputObj | Add-Member -MemberType NoteProperty -Name Serial_Number -Value $systemBios
$OutputObj | Add-Member -MemberType NoteProperty -Name IP_Address -Value $IPAddress
$OutputObj | Add-Member -MemberType NoteProperty -Name MAC_Address -Value $MACAddress
$OutputObj | Add-Member -MemberType NoteProperty -Name Last_User -Value $username.Name
$OutputObj | Add-Member -MemberType NoteProperty -Name User_Last_Login -Value $username.LastWriteTime
$OutputObj | Add-Member -MemberType NoteProperty -Name C:_FreeSpace_GB -Value $driveSpace.GBfreespace
$OutputObj | Add-Member -MemberType NoteProperty -Name Total_Memory_GB -Value $totalMemory
$OutputObj | Add-Member -MemberType NoteProperty -Name Last_ReBoot -Value $lastboot
$OutputObj | Export-Csv $exportLocation -Append -NoTypeInformation
}
When I run the script, I get the errors below and not quite sure how to address them. I've also noticed that the line supposed to output the system's RAM always outputs 0. Any guidance would be much appreciated. I'm running Powershell 3 on Windows 7 if that makes any difference.
Win32_computerSystem : The term 'Win32_computerSystem' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
Get-WmiObGet-WmiObject : The term 'Get-WmiObGet-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
Get-WmiObjectject : The term 'Get-WmiObjectject' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
Syntax errors
Line 15:
$Bios = Win32_computerSystem -Computername $Computer
You forgot to prefix Win32_ComputerSystem with Get-WmiObject. It's attempting to run Win32_ComputerSystem as a command, not evaluate a WMI class. To fix it, change the line to look like this:
$Bios = Get-WmiObject Win32_ComputerSystem -ComputerName $Computer
Line 16:
$Sysbuild = Get-WmiObGet-WmiObject win32_bios -Computername $Computer
There is no cmdlet called Get-WmiObGet-WmiObject. Change it to Get-WmiObject:
$Sysbuild = Get-WmiObject Win32_Bios -ComputerName $Computer
Line 17:
$Hardware = Get-WmiObjectject Win32_WmiSetting -Computername $Computer
This is another typo when trying to call Get-WmiObject. Correct the mispelling and it should work:
$Hardware = Get-WmiObject Win32_WmiSetting -ComputerName $Computer
Why your RAM is always zero
Simply put, you're using the wrong WMI class when you set $Hardware. You can get the physical memory information from the Win32_PhysicalMemory class. Replace line 17 with:
$Hardware = Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer
and when you get the $totalRam, you can use the following calculation:
$totalRamBytes = 0
$Hardware.Capacity | Foreach-Object { $totalRamBytes += $_ }
$totalRamGb = $totalRamBytes / 1GB

ADSI query running well on some boxes and failing on others

I am working on a PowerShell script for a customer to pull information from Servers before they are decommissioned. I have had to jump through a couple of hoops, as they have 2008 and even some 2003 servers, which don't always support the same Get-CimInstance queries, but for the most part it is working as expected. One section I have as yet been unable to fix however is pulling a list of all local groups and their members, like so:
$localGroups = Invoke-Command -ScriptBlock {
[ADSI]$S = "WinNT://$($env:computername)"
$S.children.Where({$_.class -eq 'group'}) |
Select #{Name="Name";Expression={$_.name.value}},
#{Name="Members";Expression={
[ADSI]$group = "$($_.Parent)/$($_.Name),group"
$members = $Group.psbase.Invoke("Members")
($members | ForEach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -join ";"
}
}
} -ComputerName $sPC | Select PSComputername,Name,Members
This works just fine on Server 2012 and above, but fails on 2008 and below. The specific error states:
Method invocation failed because [System.DirectoryServices.DirectoryEntries] doesn't contain a method named 'Where'
So the OS does not like the $S.Children.Where() call. Just curious if anyone knows of another way to format it for use with 2008 and earlier. I could probably go the old WMI call route, but that takes forever to finish.
I ended up finding a (fairly) quick way of doing it, works on all OS flavors:
function get-groups {
param ($strcomputer)
$groups = gwmi win32_group -ComputerName $strcomputer
return $groups
}
function Get-LocalGroupMembers {
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Alias("Name")]
[string]$ComputerName,
[string]$GroupName = "Administrators"
)
begin {}
process {
$ComputerName = $ComputerName.Replace("`$", '')
$arr = #()
$wmi = Get-WmiObject -ComputerName $ComputerName -Query "SELECT * FROM Win32_GroupUser WHERE GroupComponent=`"Win32_Group.Domain='$ComputerName',Name='$GroupName'`""
if ($wmi -ne $null) {
foreach ($item in $wmi) {
$arr += ($item.PartComponent.Substring($item.PartComponent.IndexOf(',') + 1).Replace('Name=', '').Replace("`"", ''))
}
}
$hash = #{ComputerName=$ComputerName;Members=$arr}
return $hash
}
end{}
}
$sPC = "Server2008R2"
$a = 1
$adapterInfo = Get-CimInstance -query "Select * From
Win32_NetworkAdapterConfiguration Where IPenabled = 'TRUE'" -ComputerName $sPC
$serialNumber = Get-CimInstance -query "Select * From Win32_Bios" -ComputerName $sPC
$shares = Get-CimInstance -query "Select * From Win32_Share" -ComputerName $sPC
$localGroups = get-groups $sPC
$myObject = New-Object -TypeName PSObject
$myObject | Add-Member -MemberType NoteProperty -Name ComputerName -Value $adapterInfo.PSComputerName
$myObject | Add-Member -MemberType NoteProperty -Name Description -Value $adapterInfo.Description
$adapterInfo | ForEach-Object {
$_.IPAddress |
ForEach-Object {
$myObject | Add-Member -MemberType NoteProperty -Name "IPAddress$($a)" -Value $_
$a++
}
}
$myObject | Add-Member -MemberType NoteProperty -Name SerialNumber -Value $serialNumber.SerialNumber
foreach ($share in $shares) {
if ($share.Name -ne "C$" -and
$share.Name -ne "D$" -and
$share.Name -ne "ADMIN$" -and
$share.Name -ne "IPC$") {
$myObject | Add-Member -MemberType NoteProperty -Name "Share $($share.Name)" -Value $share.Path
}
}
foreach ($group in $localGroups) {
$members = ((Get-LocalGroupMembers -ComputerName $sPC -GroupName $group.Name).Members) -join "; "
if ($members.Length -ne 0) {
$myObject | Add-Member -MemberType NoteProperty -Name "$($group.Name) Members" -Value $members
}
}
$myObject | Export-Csv -Path "<Path to Folder>\$($sPC).csv" -NoTypeInformation

How can i get the disk details in csv format in windows server using powershell

Hi all I want to get details in below format
Hostname Drive_0 Drive_1 Drive_2
Name C: 99.899227142334 d: 99.899227142334 e: 99.899227142334
I can get this detail using below script but this works on PowerShell 3.0
how can I change to execute on PowerShell 2.0
$result = #()
$obj = new-object PSobject
$server = hostname
$obj |Add-Member -MemberType NoteProperty -Name "Hostname" -Value $server -ErrorAction SilentlyContinue
$z = Get-WmiObject -Class win32_Logicaldisk -Filter 'DriveType=3' | Select-Object -Property DeviceID, #{LABEL='TotalSize';EXPRESSION={$_.Size/1GB}}
$z3 = $z.DeviceID
$z4 = $z.TotalSize
$i = 0
foreach($z3 in $z3){
$z1 = $z.DeviceID[$i]
$z2 = $z.TotalSize[$i]
$zx = "$z1" + ": $z2"
$obj | Add-Member -MemberType NoteProperty -Name "Drive_$i" -Value $zx -ErrorAction SilentlyContinue
$i++
}
$result+=$obj
$result | Export-Csv "$env:userprofile\Desktop\Result.csv" -NoTypeInformation
You can change your code to the below. It's a bit neater and sorts out your loops and limits so you don't need to manage them
$result = #()
$obj = new-object PSobject
$server = hostname
$obj |Add-Member -MemberType NoteProperty -Name "Hostname" -Value $server -ErrorAction SilentlyContinue
$z = Get-WmiObject -Class win32_Logicaldisk -Filter 'DriveType=3' | Select-Object -Property DeviceID, #{LABEL='TotalSize';EXPRESSION={$_.Size/1GB}}
$i = 0
$z | % {
$z1 = $_.DeviceID
$z2 = $_.TotalSize
$zx = "$z1" + ": $z2"
$obj | Add-Member -MemberType NoteProperty -Name "Drive_$i" -Value $zx
$i++
}
$result+=$obj
$result | Export-Csv "$env:userprofile\Desktop\Result.csv" -NoTypeInformation
I also removed the -ErrorAction off the Add-Member as you should try and handle anything that crops up yourself, but add it back if you feel the need to.

Obtaining Required columns in HTML output in Powershell

I obtained the BIOS data and saved it in HTML file but i don't want all the data to be in the file and i also need to format it so that it could suite my requirement.
Code:
$bios = get-wmiobject -class "Win32_BIOS" -namespace "root\CIMV2"
[string]$body = $bios | ConvertTo-Html -As List| Out-File c:/d/d/Test.htm
So based on the discussion in the comments, I think you are looking for something like this:
function GetCompInfoWork
{
param (
[string]$computername,[string]$logfile
)
$os = Get-WmiObject win32_operatingsystem -ComputerName $computername
$bios = Get-WmiObject win32_bios -ComputerName $computername
$disk = Get-WmiObject win32_logicalDisk -Filter "DeviceID= 'C:'" `
-computername $computername
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty `
-Name ComputerName -Value ($os.csname)
$obj | Add-Member -MemberType NoteProperty `
-Name Manufacturer -Value ($bios.manufacturer)
$obj | Add-Member -MemberType NoteProperty `
-Name SysDriveFree -Value ($disk.freespace / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name SerialNumber -Value ($bios.serialnumber)
$obj | Add-Member -MemberType NoteProperty `
-Name Version -Value ($bios.version)
Write-Output $obj
}
function Get-CompInfo
{
param ([string[]]$computername,[string]$logfile )
BEGIN
{
$usedParamater = $False
if ($PSBoundParameters.ContainsKey('computername')) {
$usedParamater = $True
}
}
PROCESS {
if ($usedParamater)
{
foreach ($computer in $computername)
{
Getcompinfowork -computername $computer `
-logfile $logfile
}
}
else
{
Getcompinfowork -computername $_ `
-logfile $logfile
}
}
END {}
}
Get-CompInfo -computername localhost | ConvertTo-Html | Out-File C:\Output.html
Try this:
$freeSpace = (gwmi Win32_logicaldisk -Filter "DeviceID = 'C:'").FreeSpace
gwmi Win32_BIOS `
| select PSComputerName,Manufacturer,SerialNumber,Version,
#{n="AvailableSpace";e={[int]($freeSpace / 1MB)}} `
| ConvertTo-Html `
| Out-File "C:/d/d/Test.htm"

How to get name and in a sequence in Powershell

When I run the below code I get an error with Model Number in which the heading is not being displayed and one more thing is i am unable to get all the three of them in a sequence.
$arrComputers = get-Content -Path "C:\Desktop\Computers.txt"
$e=$arrComputers | ForEach-Object {Get-WMIObject -Class Win32_BIOS -ComputerName $_ } |Select PSComputerName, Version,Manufacturer,Status,BIOSVersion,SerialNumber |ConvertTo-Html -fragment
$e2=$arrComputers |ForEach-Object { get-wmiobject -class Win32_logicaldisk -Filter "DeviceID = 'C:'" -ComputerName $_ } | select freeSpace,size | ConvertTo-Html -fragment
$e3=$arrComputers |ForEach-Object { get-wmiobject -class "Win32_ComputerSystem" -ComputerName $_ } | select Model| ConvertTo-Html -fragment
ConvertTo-HTML -Body "$e $e2 $e3" -Title "List of Computers" | Out-File C:\Users\Desktop\gf.html
Its a lot easier to make all of the WMI calls into a single object. It is much easier to handle formatting. I think I got everything that you were wanting:
function GetCompInfoWork
{
param (
[string]$computername,[string]$logfile
)
$pc = Get-WmiObject Win32_ComputerSystem -ComputerName $computername
$bios = Get-WmiObject win32_bios -ComputerName $computername
$disk = Get-WmiObject win32_logicalDisk -Filter "DeviceID= 'C:'" `
-computername $computername
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty `
-Name PSCompName -Value ($bios.PSComputerName)
$obj | Add-Member -MemberType NoteProperty `
-Name Version -Value ($bios.version)
$obj | Add-Member -MemberType NoteProperty `
-Name Manufacturer -Value ($bios.manufacturer)
$obj | Add-Member -MemberType NoteProperty `
-Name Status -Value ($bois.status)
$obj | Add-Member -MemberType NoteProperty `
-Name SerialNumber -Value ($bios.serialnumber)
$obj | Add-Member -MemberType NoteProperty `
-Name DiskSize -Value ($disk.size / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name SysDriveFree -Value ($disk.freespace / 1GB -as [int])
$obj | Add-Member -MemberType NoteProperty `
-Name ComputerName -Value ($pc.model)
Write-Output $obj
}
function Get-CompInfo
{
param ([string[]]$computername,[string]$logfile )
BEGIN
{
$usedParamater = $False
if ($PSBoundParameters.ContainsKey('computername')) {
$usedParamater = $True
}
}
PROCESS {
if ($usedParamater)
{
foreach ($computer in $computername)
{
Getcompinfowork -computername $computer `
-logfile $logfile
}
}
else
{
Getcompinfowork -computername $_ `
-logfile $logfile
}
}
END {}
}
Get-Content C:\Users\Kev\Desktop\computers.txt| Get-CompInfo | ConvertTo-Html | Out-File C:\Users\kev\Desktop\Output.html