Como é que adiciono uma nova linha à saída de comandos em PowerShell?

Eu corro o seguinte código usando o PowerShell para obter uma lista de programas Adicionar / Remover do registo:

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { Write-Output $_.GetValue("DisplayName") } `
    | Out-File addrem.txt

quero que a lista seja separada por linhas novas por cada programa. Eu tentei.

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

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object {$_.GetValue("DisplayName") } `
    | Write-Host -Separator `n

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

mas tudo resulta em Formatação estranha quando a saída para a consola, e com três caracteres quadrados após cada linha quando a saída para um arquivo. Eu tentei.Format-List, Format-Table, e sem sorte. Originalmente, eu pensei que algo assim funcionaria:

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { "$_.GetValue("DisplayName") `n" }
Mas isso deu-me erro.

Author: Peter Mortensen, 2009-10-28

5 answers

Ou, basta definir o separador do campo de saída para duplicar as linhas novas, e depois certifique-se de obter um texto quando o enviar para o ficheiro:

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

Cuidado para usar o ` e não a '. No meu teclado (US-English QWERTY layout) está localizado à esquerda do 1.
(Moved here from the comments - Thanks Koen Zomers)

 72
Author: Jaykul, 2018-04-13 00:20:09
Experimenta isto.
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

Dá o seguinte texto no meu addrem.ficheiro txt:

Adobe AIR

Adobe Flash Player 10 ActiveX

...

Nota: No meu sistema, o GetValue("DisplayName") devolve nulo para alguns itens, pelo que os Filtro. Já agora, estiveste perto disto.

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

Excepto que dentro de uma string, se precisar de aceder a uma propriedade de uma variável, isto é, "avaliar uma expressão", então terá de usar uma sintaxe de sub-expressão como assim:

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

Essencialmente dentro de uma cadeia de caracteres de dupla citação irá expandir variáveis como $_, mas não irá avaliar expressões a menos que coloque a expressão dentro de uma sub-expressão usando esta sintaxe:

$(`<Multiple statements can go in here`>).
 68
Author: Keith Hill, 2014-12-27 14:39:51
Em última análise, o que você está tentando fazer com as linhas extras em branco entre cada uma é um pouco confuso:)

Eu acho que o que você realmente quer fazer é usar Get-ItemProperty . Você vai ter erros quando os valores estão faltando, mas você pode suprimi-los com -ErrorAction 0 ou simplesmente deixá-los como lembretes. Dado que o fornecedor do registo devolve propriedades extra, você irá querer colar num Select-Object que usa as mesmas propriedades que as propriedades Get-Properties.

Então se cada propriedade em uma linha com uma linha em branco entre, use Format-List (caso contrário, use Format-Table para obter uma por linha).

gci -path hklm:\software\microsoft\windows\currentversion\uninstall |
gp -Name DisplayName, InstallDate | 
select DisplayName, InstallDate | 
fl | out-file addrem.txt
 6
Author: Jaykul, 2014-12-27 14:47:14
Acho que tiveste a ideia certa com o teu último exemplo. Só teve um erro porque estava a tentar colocar aspas dentro de um texto já citado. Isto vai corrigi-lo.
gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output ($_.GetValue("DisplayName") + "`n") }

Edit: o operador $() do Keith realmente cria uma sintaxe melhor (esqueço-me sempre deste). Você também pode escapar de aspas dentro das aspas como assim:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output "$($_.GetValue(`"DisplayName`"))`n" }
 4
Author: Ludovic Chabant, 2009-10-28 21:23:01

A opção que eu costumo usar, principalmente porque é simples e não tenho que pensar, é usar Write-Output como abaixo. Write-Output irá colocar um marcador de EOL na string para você e você pode simplesmente sair a string acabada.

Write-Output $stringThatNeedsEOLMarker | Out-File -FilePath PathToFile -Append

Em alternativa, você também pode simplesmente compilar o texto inteiro usando Write-Output e, em seguida, empurrar o texto acabado para Out-File.

 4
Author: InfoSponge, 2014-12-27 14:49:58