Remove blank space from text file - powershell

I have a script to import the names of the virtual machines from hyper-v to a txt file.
The problem is that sometimes the names have blank spaces on the back, and when I try to turn them off or on with the script it does not find those machines because of the blank spaces.
Any way to remove the blank spaces from the file?
$vm = Get-VM | select name | Out-File -FilePath $ListVM
(Get-Content $ListVM | Select-Object -Skip 3) | ? {$_.trim() -ne ""} | Set-Content $ListVM

Withstanding Santiago's relevant alternate comment/approach. the cause of your issue may be:
Generally the Out-* cmdlets will force objects through PowerShell's for-display formatting system. You can use Set-Content from the start to avoid this, however you cannot simply select the name property doing so will create objects with the single property named "name". When Set-Content sees that it will write hash/object syntax to the file trying to represent the object, like:
#{Name=MachineName}
To avoid this simply expand the property you want to store in the file:
Get-VM |
Select-Object -ExpandProperty Name |
Set-Content -FilePath $ListVM
Or:
(Get-VM).Name | Set-Content -FilePath $ListVM
Note: you are assigning $VM to the output, however that will result in $VM being null. I'm not sure what the intent is, but if you want the resulting list stored in the variable add the -PassThru parameter like:
$vm = (Get-VM).Name | Set-Content -FilePath $ListVM -PassThru

Related

Out-file , txt are created , no data saved [duplicate]

I'm new to scripting and I am trying to write the information returned about a VM to a text file. My script looks like this:
Connect-VIServer -Server 192.168.255.255 -Protocol https -User xxxx -Password XXXXXX
Get-VM -Name xxxxxx
Get-VM xxxxx | Get-HardDisk | Select Parent, Name, Filename, DiskType, Persistence | FT -AutoSize
Out-File -FilePath C:Filepath
I am able to connect to the VM, retrieve the HDD info and see it in the console. The file is created where I want it and is correctly named. No data is ever put into the file. I have tried Tee-Object with the same results. I've also tried the -append switch. I did see a post about the data being returned as an array and Powershell is not able to move the data from an array to a string. Do I need to create a variable to hold the returned data and write to file from there?
Thanks
Guenther Schmitz' answer is effective, but it's worth explaining why:
Your Out-File -FilePath C:Filepath is a stand-alone command that receives no input.
An Out-File call with no input simply creates an empty file (0 bytes).
In order for cmdlets such as Out-File to receive input from (an)other command(s) (represented as ... below), you must use the pipeline, which means that you must place a | after the input command(s) and follow it with your Out-File call:Note that I'm using the shorter -Path parameter alias for the less commonly used -FilePath[1]
... | Out-File -Path C:Filepath
In the simplest case, as above, the entire command (pipeline) is placed on the same line; if you want to spread it across multiple lines for readability, you have have two choices:
Put a line break immediately after |, which tells PowerShell that the command continues on the next line:
... |
Out-File -Path C:Filepath
End a line with an explicit line continuation, which means placing ` at the very end of a line:
... `
| Out-File -Path C:Filepath
Alternatively, since you're using Out-File with its default behavior, you could use >, an output redirection, instead:
... > C:Filepath
A couple of asides:
Using Out-File with something other than strings, and using Format-* cmdlets in general, means that the output is only suitable for display (human consumption), not for further programmatic processing.
If you want to send output to both the console and a file, use the Tee-Object cmdlet, as TobyU suggests:
... | Tee-Object -Path C:Filepath
[1] Strictly speaking, -LiteralPath is the best choice in this case, because -Path interprets its arguments as wildcard expressions. However, omitting -Path, i.e. specifying the file path as a positional argument, as is common, implicitly binds to -Path.
try this:
Get-VM xxxxx |
Get-HardDisk |
Select Parent, Name, Filename, DiskType, Persistence |
Out-File -FilePath C:\Filepath

Powershell Output File column too narrow

I am trying to list current installed applications and the DisplayVersion keeps getting its column shortened when I want it to show as normal on one line. It runs fine when running the code in a PS session but when running from a ps1 script file, the output for DisplayVersion is 1 character wide with NewLines for each integer.
$FormatEnumerationLimit = -1
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object Publisher, DisplayName, DisplayVersion |
Where {$_.DisplayName} |
Sort-Object -Property Publisher,DisplayName,DisplayVersion |
Format-Table -AutoSize -Wrap > $FullFileName
Considering the exact suggestion from LotPings, I am making this as an answer because it makes more sense to dump it in File using out-file & use Encoding instead of redirection.
Replace this:
Format-Table -AutoSize -Wrap > $FullFileName
To:
Out-File $FullFileName -Width 300 -Encoding Ascii

Writing console output to a file - file is unexpectedly empty

I'm new to scripting and I am trying to write the information returned about a VM to a text file. My script looks like this:
Connect-VIServer -Server 192.168.255.255 -Protocol https -User xxxx -Password XXXXXX
Get-VM -Name xxxxxx
Get-VM xxxxx | Get-HardDisk | Select Parent, Name, Filename, DiskType, Persistence | FT -AutoSize
Out-File -FilePath C:Filepath
I am able to connect to the VM, retrieve the HDD info and see it in the console. The file is created where I want it and is correctly named. No data is ever put into the file. I have tried Tee-Object with the same results. I've also tried the -append switch. I did see a post about the data being returned as an array and Powershell is not able to move the data from an array to a string. Do I need to create a variable to hold the returned data and write to file from there?
Thanks
Guenther Schmitz' answer is effective, but it's worth explaining why:
Your Out-File -FilePath C:Filepath is a stand-alone command that receives no input.
An Out-File call with no input simply creates an empty file (0 bytes).
In order for cmdlets such as Out-File to receive input from (an)other command(s) (represented as ... below), you must use the pipeline, which means that you must place a | after the input command(s) and follow it with your Out-File call:Note that I'm using the shorter -Path parameter alias for the less commonly used -FilePath[1]
... | Out-File -Path C:Filepath
In the simplest case, as above, the entire command (pipeline) is placed on the same line; if you want to spread it across multiple lines for readability, you have have two choices:
Put a line break immediately after |, which tells PowerShell that the command continues on the next line:
... |
Out-File -Path C:Filepath
End a line with an explicit line continuation, which means placing ` at the very end of a line:
... `
| Out-File -Path C:Filepath
Alternatively, since you're using Out-File with its default behavior, you could use >, an output redirection, instead:
... > C:Filepath
A couple of asides:
Using Out-File with something other than strings, and using Format-* cmdlets in general, means that the output is only suitable for display (human consumption), not for further programmatic processing.
If you want to send output to both the console and a file, use the Tee-Object cmdlet, as TobyU suggests:
... | Tee-Object -Path C:Filepath
[1] Strictly speaking, -LiteralPath is the best choice in this case, because -Path interprets its arguments as wildcard expressions. However, omitting -Path, i.e. specifying the file path as a positional argument, as is common, implicitly binds to -Path.
try this:
Get-VM xxxxx |
Get-HardDisk |
Select Parent, Name, Filename, DiskType, Persistence |
Out-File -FilePath C:\Filepath

Compare two text files with duplicates and write the distinct differences to text file

I want to compare 2 text files and output the difference in another text file.
compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) | Select-Object -ExpandProperty InputObject | Out-File $Location
hostname_old.txt
server02
server05
server04
server06
server01
hostname_new.txt (has duplicate names)
server04
server01
server02
server04
server02
Result:
server04
server02
server05
server06
Note how server04 and server02 are present in this list of differences, even though they're present in both input files.
This is what I want:
server05
server06
Use Select-Object -Unique to eliminate the duplicates before comparing:
compare-object -PassThru `
(get-content c:\temp\hostname_old.txt) `
(get-content c:\temp\hostname_new.txt | Select-Object -Unique)
As in this answer to your previous question, -PassThru is used to pass out the differing lines directly, without the [pscustomobject] wrappers (that indicate the source set of the difference via their .SideIndicator property) that Compare-Object outputs by default.

How do I remove carriage returns from text file using Powershell?

I'm outputting the contents of a directory to a txt file using the following command:
$SearchPath="c:\searchpath"
$Outpath="c:\outpath"
Get-ChildItem "$SearchPath" -Recurse | where {!$_.psiscontainer} | Format-Wide -Column 1'
| Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
What I end up with when I do this is a txt file with the information I need, but it adds numerous carriage returns I don't need, making the output harder to read.
This is what it looks like:
c:\searchpath\directory
name of file.txt
name of another file.txt
c:\searchpath\another directory
name of some file.txt
That makes a txt file that requires a lot of scrolling, but the actual information isn't that much, usually a lot less than a hundred lines.
I would like for it to look like:
c:\searchpath\directory
nameoffile.txt
c:\searchpath\another directory
another file.txt
This is what I've tried so far, not working
$configFiles=get-childitem "c:\outpath\*.txt" -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace "'n", ""} |
Set-Content $file.PSPath
}
I've also tried 'r but both options leave the file unchanged.
Another attempt:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line}'
| Set-Content -Path c:\outpath\contents2.txt
When I run that string without the Set-content at the end, it appears exactly as I need it in the ISE, but as soon as I add the Set-Content at the end, it once agains carriage returns where I don't need them.
Here's something interesting, if I create a text file with a few carriage returns and a few tabs, then if I use the same -replace script I've been using, but uset to replace the tabs, it works perfect. Butr and n do not work. It's almost as though it doesn't recognize them as escape characters. But if I addr and `n in the txt file then run the script, it still doesn't replace anything. Doesn't seem to know what to do with it.
Set-Content adds newlines by default. Replacing Set-Content by Out-File in your last attempt in your question will give you the file you want:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line} |
Out-File -FilePath c:\outpath\contents2.txt
It's not 'r (apostrophe), it's a back tick: `r. That's the key above the tab key on the US keyboard layout. :)
You can simply avoid all those empty lines by using Select-Object -ExpandProperty Name:
Get-ChildItem "$SearchPath" -Recurse |
Where { !$_.PSIsContainer } |
Select-Object -ExpandProperty Name |
Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
... if you don't need the folder names.