PowerShell export "Get-volume" to excel/csv - excel

I used the below one it gives somewhat different in excel ,please help me on this
#Disk Space
Get-Volume
$results = Get-Volume | Export-Csv -Path C:\temp\software1.csv
Note: I need health check , Drive Name, Free space , size, disk type in excel
Thanks in advance friends :)

Generally speaking, when you run a powershell command it only shows what sections are deemed as important. If you take the same command and pipe it to format-list (or "ft" for short) you will get everything.
Get-Volume | ft
When exporting it exports everything.
Also, you need to add the paramater -NoTypeInformation to get rid of the first row.
To only get certain values, you will just pipe it using select.. something like this:
Get-Volume | select HealthStatus, DriveLetter, SizeRemaining,DriveType | Export-Csv -NoTypeInformation -Path C:\temp\software1.csv
Also, there is no need to do $results = get-volume... This pushes the output into the variable $results. This would be applicable if you wanted to recall the variable later. So, you could also do something like this..
$results = Get-Volume
$results | select HealthStatus, DriveLetter, SizeRemaining, DriveType | Export-Csv -NoTypeInformation -Path C:\temp\software1.csv

Keep in mind you need to have the Import-Excel Module loaded but you should be able to use this to output to Excel.
#check-DiskSpace_FSs.ps1
import-module activedirectory
$dc = "domainController09"
$currentDate = get-date -Format yyyyMMdd_HHmm
$path = "\\UNC\export\FileServer_DiskSpace\FileServer_DiskSpace_$currentDate.xlsx"
$smtpServer = "10.10.10.10"
$from = "me#somewhere.com"
$to = "me#somewhere.com"
$subject = "Server FS diskspace - $date"
$ServerFSs = get-adcomputer -Server $dc -SearchBase "OU=fs,OU=Server,DC=somewhere,DC=com" -filter * | select name | sort Name
$DriveSize = foreach ($FS in $somewhereFSs)
{
get-WmiObject win32_logicaldisk -ComputerName $FS.name -Filter "Drivetype=3" | select SystemName,DeviceID,#{n="TotalSize(GB)";e={$_.Size / 1gb -as [int] }}`
,#{n="FreeSize(GB)";e={$_.freespace / 1gb -as [int] }}`
,#{n="FreeSize(%)";e={[int]($_.Freespace*100/$_.Size)}},VolumeName | Export-Excel -Path $path -append -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter
}
Send-Mailmessage -smtpServer $smtpServer -from $from -to $to -subject $subject -Attachments $path -priority High

Related

Powershell Separate csv data into separate rows

I have the following script and it gets me the info I need.
$Monitors = Get-WmiObject WmiMonitorID -Namespace root\wmi
$LogFile = "d:\monitors.csv"
"Manufacturer,Name,Serial" | Out-File $LogFile
ForEach ($Monitor in $Monitors)
{
$Manufacturer = ($Monitor.ManufacturerName|where {$_ -ne 0}|ForEach{[char]$_}) -join ""
$Name = ($Monitor.UserFriendlyName |where {$_ -ne 0}| ForEach{[char]$_}) -join ""
$Serial = ($Monitor.SerialNumberID |where {$_ -ne 0}| ForEach{[char]$_}) -join ""
"$Manufacturer,$Name,$Serial" | Out-File $LogFile -append
}
My problem is the data is exported to the excel spreadsheet like this..
Manufacturer,Name,Serial.
ACI,VE248,K8LMQS048382
HWP,HP P232,6CM8122DXL
HWP,HP P232,6CM7241DRB
I need it to be:
Manufacturer Name Serial
in the spreadsheet, and when I do the next pc, it adds to the next line and so on.
I have looked online and the examples just don't match.
Does anyone have any advice?
As others already commented, use Export-Csv to write out the wanted data in csv format, rather than constructing it manually.
That means your ForEach-Object loop should emit objects instead of lines of concatenated strings.
Also, nowadays, I would use the newer Get-CimInstance instead of Get-WmiObject (What's the difference)
Try
$LogFile = "d:\monitors.csv"
Get-CimInstance -ClassName WmiMonitorID -Namespace root\wmi | ForEach-Object {
[PsCustomObject]#{
Manufacturer = [string]::new($_.ManufacturerName, 0, $_.ManufacturerName.Length).Trim("`0")
Name = [string]::new($_.UserFriendlyName, 0, $_.UserFriendlyName.Length).Trim("`0")
Serial = [string]::new($_.SerialNumberID, 0, $_.SerialNumberID.Length).Trim("`0")
}
} | Export-Csv -Path $LogFile -NoTypeInformation -UseCulture
The -UseCulture switch makes sure the output csv file uses the same delimiter characters your locally installed Excel would expect, so you can simply double-click the file to open it in Excel

Powershell get infos about files and try to Export them

I try do write a script where i can choose a folder and powershell shows me the Name, Size,.... of all the files in that folder. After that powershell should export the Informations in a Excel Table.
But im stuck and dont know what to do :C
Here is my code that i tried to build
Function Get-Folder($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null
$foldername = New-Object System.Windows.Forms.FolderBrowserDialog
$foldername.Description = "Select a folder"
$foldername.rootfolder = "MyComputer"
if($foldername.ShowDialog() -eq "OK")
{
$folder += $foldername.SelectedPath
}
return $folder
}
$a = Get-Folder
$folder = $a
Get-ChildItem -Path $folder | SELECT Name, #{Name="Size In KB";Expression={$_.Length / 1Kb}}, Attributes, LastaccessTime, #{n='Owner';e={(get-acl $_.Fullname).Owner}}| Format-Table -AutoSize
Export-Csv "C:\Users\DZimmermann\Desktop\Test.csv" -Delimiter ";" -Append
As commented, using Format-Table -AutoSize simply outputs the info in a table format to console. It returns nothing, so there is nothing to write in the csv file..
Doing like this will create the CSV file and writes the info in there:
Get-ChildItem -Path $folder |
Select-Object Name,
#{Name="Size In KB";Expression={$_.Length / 1Kb}},
Attributes, LastaccessTime,
#{n='Owner';e={(get-acl $_.Fullname).Owner}} |
Export-Csv "C:\Users\DZimmermann\Desktop\Test.csv" -Delimiter ";"
This will not get you the info on screen. If you also want that, capture the result in a variable first:
$result = Get-ChildItem -Path $folder |
Select-Object Name,
#{Name="Size In KB";Expression={$_.Length / 1Kb}},
Attributes, LastaccessTime,
#{n='Owner';e={(get-acl $_.Fullname).Owner}}
#output on screen
$result | Format-Table -AutoSize
# write the CSV file:
$result | Export-Csv "C:\Users\DZimmermann\Desktop\Test.csv" -Delimiter ";"
P.S. judging by the title of this question, I think you only want info about Files, not Directories..
If that is the case, add -File switch to the Get-ChildItem cmdlet (for PS 3 and up). For PS versions below 3 use
Get-ChildItem -Path $folder | Where-Object { !$_.PSIsContainer }

powershell script, text placement in cells in csv file

So, to continue my lovely journey through powershell from here:
Loop for two variables
I have a ps1 that runs a loop for a bunch of transactions and a bunch of nodes and sends them over to a csv file.
$url = "https://someserver/trans="
$transactions = '1','2','3','4' #There are 4 transactions
$nodes = 'node1','node2','node3','node4','node5','node6' #There are 10 nodes
Remove-Item ATM.csv -Force
# So far so good
# Below is what I'd use as a function in bash. No sure what/how to do in PS:
#OUTPUT:
foreach($transaction in $transactions)
{
foreach($node in $nodes)
{
"$transaction;$node" |out-file -Append ATM.csv
curl -k -u user#pass $url$transaction$node | findstr "<value>" | out-file -Append ATM.csv
}
}
Opening the file in excel, I end up with this output under column A:
transaction1;node1 (in the first row, left-most cell)
value1 (from the curl. It's actually a number and it sits in the row right under the first entry)
and so on and so forth for 2,3, and the rest. only the left most column (column A) gets populated.
What I'd like to get is a way to place the values in three columns, such that the csv will look like:
Column A | Column B | Column C
transaction1| node1 | valueX
transaction2| node2 | valueY
and so on. The script or another will have to do this, the end user for this job who'll run the script will not open excel every day and start running macros, he needs the final csv ready from the script.
Whatever shall I do?
Something like this will fix your issues, the only bit that's not included is selecting the value itself from Invoke-WebRequest (curl) as that will change depending on what's returned.
foreach($transaction in $transactions)
{
foreach($node in $nodes)
{
$value = Invoke-WebRequest -Uri $url$transaction$node -UseBasicParsing | Select-Object -Expand Content
Add-Content -Path ATM.csv -Value "$transaction,$node,$value"
}
}
You are currently writing your output in two different lines. One solution could be to use the NoNewLine parameter in the Out-File:
"$transaction;$node" |out-file -Append ATM.csv -nonewline
curl -k -u user#pass $url$transaction$node | findstr "<value>" | out-file -Append ATM.csv
Personally I would create a Powershell Object and create the csv at the end:
$array = #()
foreach($node in $nodes) {
$obj = New-Object psobject
$obj | Add-Member -MemberType NoteProperty -Name 'Transaction' -Value $transaction
$obj | Add-Member -MemberType NoteProperty -Name 'Node' -Value $node
$obj | Add-Member -MemberType NoteProperty -Name 'Value' -Value (curl -k -u user#pass $url$transaction$node | findstr "<value>")
$array += $obj
}

Passing PowerShell Output to CSV/Excel

I previously had asked a question regarding adding together files and folders with a common name and having them summed up with a total size (Sum of file folder size based on file/folder name). This was successfully answered with the PS script below:
$root = 'C:\DBFolder'
Get-ChildItem "$root\*.mdf" | Select-Object -Expand BaseName |
ForEach-Object {
New-Object -Type PSObject -Property #{
Database = $_
Size = (Get-ChildItem "$root\$_*\*" -Recurse |
Measure-Object Length -Sum |
Select-Object -Expand Sum ) / 1GB
}
}
This now leaves me with a list that is ordered by the 'Database' Property by default. I have attempted to use a Sort-Object suffix to use the 'Size' property with no joy. I have also attempted to use Export-Csv with confounding results.
Ideally, if I could pass the results of this script to Excel/CSV so I can rinse/repeat across multiple SQL Servers and collate the data and sort within Excel, I would be laughing all the way to the small dark corner of the office where I can sleep.
Just for clarity, the output is looking along the lines of this:
Database Size
-------- ----
DBName1 2.5876876
DBName2 4.7657657
DBName3 3.5676578
Ok, it was one pipe character that I had missed when using the Export-csv function. This resolved my problem.
$root = 'C:\DB\Databases'
Get-ChildItem "$root\*.mdf" | Select-Object -Expand BaseName |
ForEach-Object {
New-Object -Type PSObject -Property #{
Database = $_
Size = (Get-ChildItem "$root\$_*\*" -Recurse |
Measure-Object Length -Sum |
Select-Object -Expand Sum ) / 1GB
}
} | Export-Csv 'C:\Test\test.csv'

Output Value from select-object calculated value

I've used a hash table to calculate some values for my VMWare inventory script, but now when I output the data, it records it as a key/value pair. I'd like to dump just the value. When I simply take what I'm handed that works fine, but when I get picky PS starts to stonewall me. :-)
Here is the relevant part of the script.
foreach ($machine in $vmList) {
$vmname = $machine.Name
$properties = #{
'Name'=Get-VM $vmname | Select -ExpandProperty Name
'RAM'=Get-VM $vmname | Select -ExpandProperty MemoryGB
'CpuCount'=Get-VM $vmname | Select -ExpandProperty NumCpu
'UsedDiskGB'=Get-VM $vmname | Select-Object #{n="UsedDiskGB"; e={[math]::Round( $_.UsedSpaceGB, 3 )}}
'TotalDiskGB'=Get-VM $vmname | Select-Object #{n="TotalDiskGB"; e={[math]::Round((Get-HardDisk -vm $_ | Measure-Object -Sum CapacityGB).Sum)}}
'Networks'=Get-VM $vmname | Select-Object #{n="Networks"; e={(Get-NetworkAdapter -VM $_ |Sort-Object NetworkName |Select -Unique -Expand NetworkName) -join '; '}}
'OS'=(Get-VM -Name $vmname | Get-View).summary.config.guestFullName
}
$object=New-Object -TypeName PSObject -Prop $properties
Export-Csv -Path $WorkDir\vms.csv -Append -Encoding UTF8 -InputObject $Object
Write-Output $Object
}
How do I get UsedDiskGB, Networks and TotalDiskGB to display just the value instead of something like '#{TotalDiskGB=80}'? Ram, OS, CpuCount and Name work exactly as desired already.
Also, suggestions on doing this in a faster way are welcome. I'm sure all these calls can be done better. I had it done in a single line, but then they asked for OS to be added and that changed everything.
Easy, but bad way:
In the expression pipe to |Select -ExpandProperty <property name> to get just the value. Such as:
'TotalDiskGB'=Get-VM $vmname | Select-Object #{n="TotalDiskGB"; e={[math]::Round((Get-HardDisk -vm $_ | Measure-Object -Sum CapacityGB).Sum)}}|select -expand totaldiskgb
The better way:
Structure your properties better to start with. Try this:
'TotalDiskGB'= [math]::Round((Get-HardDisk -vm (Get-VM $vmname) | Measure-Object -Sum CapacityGB).Sum)
The reason you're having issues is because you are creating a PSCustomObject with your Select, and Totaldiskgb is a property of that object. You don't want to make an object, you just want the value of that property.
Edit: Thank you to #briantist for pointing out that Get-VM $vmname should be called once, and stored as an object to be used later, rather than called for each time it is needed for a member of $Properties. For example:
foreach ($machine in $vmList) {
$vmname = $machine.Name
$vmobject = Get-VM $vmname
$properties = #{
'Name'=$vmobject | Select -ExpandProperty Name
'RAM'=$vmobject | Select -ExpandProperty MemoryGB
'CpuCount'=$vmobject | Select -ExpandProperty NumCpu
'UsedDiskGB'=[math]::Round( $vmobject.UsedSpaceGB, 3 )
'TotalDiskGB'=[math]::Round((Get-HardDisk -vm $vmobject | Measure-Object -Sum CapacityGB).Sum)
'Networks'=(Get-NetworkAdapter -VM $vmobject |Sort-Object NetworkName |Select -Unique -Expand NetworkName) -join '; '
'OS'=($vmobject | Get-View).summary.config.guestFullName
}
$object=New-Object -TypeName PSObject -Prop $properties
Export-Csv -Path $WorkDir\vms.csv -Append -Encoding UTF8 -InputObject $Object
Write-Output $Object
}

Resources