tags:

views:

2131

answers:

4

I run the following code using powershell to get a list of add/remove programs from the registry:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output $_.GetValue("DisplayName") } | out-file addrem.txt

I want the list to be separated by newlines per each program. I've tried:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output $_.GetValue("DisplayName") `n } | out-file test.txt

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach {$_.GetValue("DisplayName") } | write-host -Separator `n

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { $_.GetValue("DisplayName") } | foreach ($_) { echo $_ `n }

But all result in weird formatting when output to console, and with three square characters after each line when output to file.

I tried Format-List, Format-Table, and Format-Wide with no luck.

Originally, I thought something like this would work:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { "$_.GetValue("DisplayName") `n" }

But that just gave me an error...

+3  A: 

Give this a try:

PS> $nl = [Environment]::NewLine
PS> gci hklm:\software\microsoft\windows\currentversion\uninstall | 
        ForEach { $_.GetValue("DisplayName") } | Where {$_} | Sort |
        Foreach {"$_$nl"} | Out-File addrem.txt -Enc ascii

Yields the following text in my addrem.txt file:

Adobe AIR

Adobe Flash Player 10 ActiveX

...

Note: on my system, GetValue("DisplayName") returns null for some entries so I filter those out. BTW you were close with this:

ForEach-Object -Process { "$_.GetValue("DisplayName") `n" }

Except that within a string, if you need to access a property of a variable ie "evaluate an expression", then you need to use subexpression syntax like so:

Foreach-Object -Process { "$($_.GetValue('DisplayName'))`r`n" }

Essentially within a double quoted string PowerShell will expand variables like $_ but it won't evaluate expressions unless you put the expression within a subexpression using this syntax $(<multiple statements can go in here>).

Keith Hill
I tried both of the suggestions above and the formatting still is not 100%. Each newline shows up as a little square (unicode maybe?) in Notepad. In Wordpad everything seems fine, but Word complains about encoding. Using Foreach { "$($_.GetValue('DisplayName'))`n" } still outputs the wrong format in any file.
mike
The default output for Powershell is Unicode. I'll modify the example to show how to save in ascii format.
Keith Hill
I've tried every encoding option for out-file and none of them gave me the right results. I checked the environment variable $OutputEncoding and everything came up US-ASCII. I think I am going to try a different approach, maybe in python.
mike
A: 

I think you had the correct idea with your last example. You only got an error because you were trying to put quotes inside an already quoted string. This will fix it:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output ($_.GetValue("DisplayName") + "`n") }

Edit: Keith's $() operator actually creates a better syntax (I always forget about this one). You can also escape quotes inside quotes as so:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output "$($_.GetValue(`"DisplayName`"))`n" }
Ludovic
+3  A: 

Or, just set the output field separator to double newlines, and then make sure you get a string when you send it to file:

$OFS = "`r`n`r`n"
"$( gci -path hklm:\software\microsoft\windows\currentversion\uninstall | 
    ForEach-Object -Process { write-output $_.GetValue('DisplayName') } )" | 
 out-file addrem.txt
Jaykul
This actually worked. But, if any other values are added, i.e. $_.GetValue('InstallDate'), then it messes up. It fulfills the original question though so thanks for the help.
mike
I added an alternate answer below which I think is probably better :)
Jaykul
Works great. Beware to use the ` and not the '. On my keyboard (US-English Qwerty layout) it's located left of the 1.
Koen Zomers
+3  A: 

Ultimately, what you're trying to do with the EXTRA blank lines between each one is a little confusing :)

I think what you really want to do is use get-itemproperty. You'll get errors when values are missing, but you can suppress them with -ErrorAction 0 or just leave them as reminders. Because the Registry provider returns extra properties, you'll want to stick in a Select-Object that uses the same properties as the Get-Properties.

Then if you want each property on a line with a blank line between, use Format-List (otherwise, use Format-Table to get one per line).

gci -path hklm:\software\microsoft\windows\currentversion\uninstall |
gp -Name DisplayName, InstallDate | 
select DisplayName, InstallDate | 
fl | out-file addrem.txt
Jaykul
Yes! I should have done it this way from the beginning, instead of messing around with new lines. Thanks for the help! Really appreciate it.
mike