Append results or text to text file by using Powershell - powershell

I have a collection of objects with properties: ProductName and PartName. The content of collection is output to a file first:
$colProducts | sort-object ProductName | `
Select-object ProductName PartName | `
Format-Table -autosize ProductName, PartName | `
Out-File myProducts.txt
So far so good. However, I have trouble to append a text message to the result file like this:
Add-Content myProducts.txt "`nParts in more than one Product`n"
I found that the appended text is not readable at the end. One thing I notice is that the output of the first collection to a file is in Unicode, and the second one code (add-content) is in ASCII if only to a new file.
After this, I would like to continue to add the following information the same result file:
$colProducts | Group-object PartName | sort-object PartName | `
Where-Object {$_.Count -gt 1 } | `
Select-object ProductName PartName | `
Format-Table -autosize ProductName, PartName | `
Out-File myProducts.txt
The above codes will overwrite to the result file. I need to append to the file. Greatly appreciate help!
Update: It is good to know -Append option. How about Add-Content? It seems adding some unreadable chars to the file after Out-File from collection.

I would first try:
$colProducts | Group-object PartName | sort-object PartName | `
Where-Object {$_.Count -gt 1 } | `
Select-object ProductName PartName | `
Format-Table -autosize ProductName, PartName | `
Out-File -Append myProducts.txt
And then look at this to get a feel for what you were encountering.
Essentially, Out-File (and Out-File -Append) gives you Unicode by default and Add-Content gives ASCII by default. My advice would be stick to the same command and you shouldn't have a problem.
And, of course, help Out-File -Detailed! Always check out the powershell examples because they help a great deal, not just to figure out their common usage, but to grok them as well.

Try:
$colProducts | Group-object PartName | sort-object PartName | `
Where-Object {$_.Count -gt 1 } | `
Select-object ProductName PartName | `
Format-Table -autosize ProductName, PartName | `
Out-File -Append myProducts.txt

Another option:
$colProducts | sort-object ProductName | `
Select-object ProductName PartName | `
Format-Table -autosize ProductName, PartName | `
Out-String | Add-Content myProducts.txt
Add-Content myProducts.txt "`nParts in more than one Product`n"

Related

How can I get rid of unnecessary columns in powershell query output

I have this code below, when I run it the output file has additional columns like Comment, RowError, RowState, Table, ItemArray, HasErrors
$dataSet.Tables | Select-Object -Expand Rows |
ConvertTo-HTML -head $a –body $body |
Out-File $OutputFile
I want to get rid of these columns but dont know how to. I have checked other online resources but couldn't help. Is there anything am doing wrong here??
Try to exclude the columns you don't want with -ExcludeProperty:
$dataSet.Tables |
Select-Object -Expand Rows |
Select-Object * -ExcludeProperty Comment, RowError, RowState, Table, ItemArray, HasErrors |
ConvertTo-HTML -head $a –body $body |
Out-File $OutputFile
You will be better off to just include the properties you want than exclude the once you don't want:
$dataSet.Tables | Select-Object -Expand Rows | Select-Object Colum1, Colum2 |
ConvertTo-HTML -head $a –body $body | Out-File $OutputFile
Using the -Property parameter works for me
$dataSet.Tables | Select-Object -Expand Rows |
ConvertTo-HTML -head $a –body $body -Property Name,Date,Address |
Out-File $OutputFile

powershell out-file how to rid of extra spaces on each line

I run this command and I get all computer hostnames in the names.txt file.
Each hostname in the file is on a separate line, but every hostname is followed with white spaces which cause an issue when I try to read this file. How can I output to this file without getting the white spaces on each line?
Get-ADComputer -Filter * | Select-Object -property name | Sort-Object -Property name | out-file -filepath C:\temp\names.txt
You have the problem that you don't just have names, you have objects with the property 'name', and you also have the problem that Out-File runs complex objects through some kind of formatting before sending them to the file.
To fix both, expand the name out to just text, and generally use Set-Content instead:
Get-ADComputer -filter * | Select-Object -ExpandProperty Name | Sort-Object | Set-Content C:\temp\names.txt
or in short form
Get-ADComputer -filter * | Select -Expand Name | Sort | sc C:\temp\names.txt
or
(Get-ADComputer -filter *).Name | sort | sc C:\temp\names.txt
expandproperty should get rid of the #()
Get-ADComputer -Filter * | sort Name | Select -expandproperty Name | %{ $_.TrimEnd(" ") } | out-file -filepath C:\temp\names
Untested no AD#home
Piping it through this should work (before piping to the out-file):
EDIT: Piping through % { $_.name } should convert #{name=VALUE} to VALUE:
% { $_ -replace ' +$','' } | % { $_.name }
Like this:
Get-ADComputer -Filter * | Select-Object -property name | Sort-Object -Property name | % { $_ -replace ' +$','' } | % { $_.name } | out-file -filepath C:\temp\names.txt

Combine output into a single table

I'm using this code which I have modified to remove some items that I don't need and I am trying to combine the output into a single table. I have gotten this far:
$SCVMs | ForEach-Object {
$VMName = Get-SCVirtualMachine $_.Name | Select -Expand Name
$ReportData = $ReportData + (Get-SCVirtualMachine $_.Name |
Get-SCVirtualHardDisk |
Select #{Label="VM Name";Expression={$VMName}},
#{Label="VHD Name";Expression={$_.Name}},
#{Label="VHD Location";Expression={$_.Location}},
#{Label="Max Disk Size (GB)";Expression={($_.MaximumSize/1GB)}},
#{Label="Disk Space Used (GB)";Expression={"{0:N2}" -f ($_.Size/1GB)}},
#{Label="Disk Space Used (%)";Expression={[math]::Round((($_.Size/1GB)/($_.MaximumSize/1GB))*100)}},
#{Label="Free Disk Space (GB)";Expression={"{0:N2}" -f (($_.MaximumSize/1GB) - ($_.Size/1GB))}} |
ConvertTo-Html -as Table -Fragment)
}
The report displays the hard drives for a particular VM in the same table but it creates a separate table for each VM. I would like to generate a single table for all the VMs with a separate row for each hard drive in the VM.
I believe the trick lies in how I select the objects and pipe them along but I'm just not experienced enough to see how to do it.
I don't need the report in HTML, CSV would be fine.
You pipe each object into ConvertTo-Html, so you get a table fragment for each object. Instead of doing that (and appending in a loop on top of that) put ConvertTo-Html outside the ForEach-Object loop.
Change this:
$SCVMs | ForEach-Object {
$VMName = ...
$ReportData = $ReportData + (Get-SCVirtualMachine $_.Name |
Get-SCVirtualHardDisk |
Select ... |
ConvertTo-Html -as Table -Fragment)
}
into this:
$ReportData = $SCVMs | ForEach-Object {
$VMName = ...
Get-SCVirtualMachine $_.Name |
Get-SCVirtualHardDisk |
Select ...
} | ConvertTo-Html -as Table -Fragment
or this (if you need to append to $ReportData):
$ReportData += $SCVMs | ForEach-Object {
$VMName = ...
Get-SCVirtualMachine $_.Name |
Get-SCVirtualHardDisk |
Select ...
} | ConvertTo-Html -as Table -Fragment
To switch to CSV output you just replace ConvertTo-Html with ConvertTo-Csv or Export-Csv.
Just take out the intermediate variables and remove the ConvertTo-Html from inside your loop. Better still export direct to CSV. Something like this:
$SCVMs | ForEach-Object {
$VMName = Get-SCVirtualMachine $_.Name | Select -Expand Name
$ReportData = $ReportData + (Get-SCVirtualMachine $_.Name | Get-SCVirtualHardDisk | Select `
#{Label="VM Name";Expression={$VMName}}, `
#{Label="VHD Name";Expression={$_.Name}}, `
#{Label="VHD Location";Expression={$_.Location}}, `
#{Label="Max Disk Size (GB)";Expression={($_.MaximumSize/1GB)}}, `
#{Label="Disk Space Used (GB)";Expression={"{0:N2}" -f ($_.Size/1GB)}}, `
#{Label="Disk Space Used (%)";Expression={[math]::Round((($_.Size/1GB)/($_.MaximumSize/1GB))*100)}}, `
#{Label="Free Disk Space (GB)";Expression={"{0:N2}" -f (($_.MaximumSize/1GB) - ($_.Size/1GB))}} | ConvertTo-HTML -as Table -Fragment) }

Table format, columns order

I need to decide the columns' orders of my table. My actual command is that one:
$tab | Sort-Object "Pourcentage" -Descending |
Format-Table -AutoSize |
Out-String -Width 4000 |
Out-File -Append O:\sigdci\public\parcoursArborescence\bilanAnalyse.txt
It gives me that order:
Derniere modification Categorie recherchee Dernier acces Dossier Pourcentage
But I need "Dossier" to be first, then "Categorie recherchee" and "Pourcentage" shall be 2nd and 3rd. How shall I proceed?
Specify the column headers in the desired order:
$tab | Sort-Object "Pourcentage" -Descending |
Format-Table 'Dossier', 'Categorie recherchee', 'Pourcentage',
'Derniere modification', 'Dernier acces' -AutoSize |
Out-String -Width 4000 |
Out-File -Append 'O:\sigdci\public\parcoursArborescence\bilanAnalyse.txt'
If you need to dynamically determine the column names you could do it like this:
$headers = $tab[0].PSObject.Properties |
Where-Object MemberType -eq NoteProperty |
Select-Object -Expand Name
However, you'd have to bring that list into your desired order somehow. Perhaps you could do it like this:
$allHeaders = 'Dossier', 'Categorie recherchee', 'Pourcentage',
'Derniere modification', 'Dernier acces'
$actualHeaders = $tab[0].PSObject.Properties |
Where-Object { MemberType -eq NoteProperty } |
Select-Object -Expand Name
$headers = $allHeaders | Where-Object { $actualHeaders -contains $_ }
$allHeaders is an array that contains all headers in the correct order. Then you remove all items that aren't present in $actualHeaders from that list, preserving the order of the remaining headers.

How to get Export-Csv to output same information as screen output?

Get-WmiObject -list | where-object {$_.name -match "win32"} | Select-Object
name,methods,properties
This displays the name, methods and properties of each Win32 class and I wanted to get this information into a CSV file.
The following however outputs doesn't output the same information.
Get-WmiObject -list | where-object {$_.name -match "win32"} | Select-Object
name,methods,properties | Export-CSV "c:\output.csv"
How can I do this?
(Updated my script as it had an error.)
You need to do some extra manual work and make sure you expand the names and join them by some delimiter:
$methods = #{n='Methods';e={ ($_.Methods | select -expand Name) -join ';'}}
$properties = #{n='Properties';e={ ($_.Properties | select -expand Name) -join ';'}}
Get-WmiObject -List |
Where-Object {$_.Name -like "Win32_*"} |
Select-Object Name,$methods,$properties |
Export-Csv .\win32.csv -NoTypeInformation
The problem here is that each WMI Object has properties that themselves are arrays and Output-CSV can't really handle that.
To fix this, you'd need to handle the arrays of arrays explicitly.
WHat specifically do you want to be output?