Powershell "out-file" command write blank file.

JasonLattin
JasonLattin used Ask the Experts™
on
I have a powershell script that opens an XML document. Reads each line. Modifies specific ones based on some values it receives. Then writes the lines back changed/unchanged as needed. I think the logic works because I have some "write-host" entries that display what is going on in the code.

But when the script finished the orignal file "c:\tempxyz\test.txt" is completely blank. The script has completely erased everything. I'm not sure where I have gone wrong.

Below is my script and ***samples of the output and the @@@ source test.txt file
-------------------------------------------

cls
$Filename = "c:\tempxyz\test.txt"

write-host -foregroundcolor "yellow" "Are you switching from :"
write-host "A = Training To Prod
write-host "B = Prod To Training

$ProdOrPreview = read-host "Choice A or B? "

(Get-Content $Filename) | Foreach-Object {            
      $TrimmedLine=$_.trim() #(Takes "$_" and removes the leading spaces
      If ($TrimmedLine.StartsWith("<JobName>")) {
            $a = $TrimmedLine -match "<\w+>(.*?)</\w+>"
            $JobName = $Matches[1]
            write-host "JobName is $JobName"
            }
      If ($TrimmedLine.StartsWith("<DrawerName>")) {
            if ($ProdOrPreview -eq 'B') {$Drawername = "Training"}
            if ($ProdOrPreview -eq 'A') {$Drawername = $JobName}
            $_ = "<DrawerName>"+$DrawerName+"</DrawerName>" #formats line to be re-written back into test.txt
            write-host "   Writing to file $_" #lets user know what got written into test.txt
            }
      } | out-file $FileName



--------------------------------------------------

*** Here is what outputs on the screen when I run it :
--------------------------------------------------
Are you switching from :
A = Training To Prod
B = Prod To Training
Choice A or B? : B

JobName is Commercial
   Writing to file <DrawerName>Training</DrawerName>
JobName is Personal
   Writing to file <DrawerName>Training</DrawerName>

-------------------------------------------------------

@@@ Below is sample test.txt file before it is edited
-------------------------------------------------------
    <MappingJobConfiguration>
                  <JobName>Commercial</JobName>
      <LocationName />
                 <DrawerName>Commercial</DrawerName>
    </MappingJobConfiguration>
    <MappingJobConfiguration>
                  <JobName>Personal</JobName>
      <JobDescription>Personal</JobDescription>
      <LocationName />
                   <DrawerName>Personal</DrawerName>
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
At first glance, you are piping your foreach into the out-file which means the only thing you will capture there will be the last value.

you can simply add -append to capture each (though I might do this completely differently)

(Get-Content $Filename) | Foreach-Object {            
      $TrimmedLine=$_.trim() #(Takes "$_" and removes the leading spaces
      If ($TrimmedLine.StartsWith("<JobName>")) {
            $a = $TrimmedLine -match "<\w+>(.*?)</\w+>"
            $JobName = $Matches[1]
            write-host "JobName is $JobName"
            }
      If ($TrimmedLine.StartsWith("<DrawerName>")) {
            if ($ProdOrPreview -eq 'B') {$Drawername = "Training"}
            if ($ProdOrPreview -eq 'A') {$Drawername = $JobName}
            $_ += "<DrawerName>"+$DrawerName+"</DrawerName>" #formats line to be re-written back into test.txt
            write-host "   Writing to file $_" #lets user know what got written into test.txt
            }
      } | out-file $FileName -append

Open in new window

Author

Commented:
@BECRAIG...
I tried the "-append" suggestion. No fix. Same blank output.

i suspect it is line 11 that messesus up. I commented out  8-13 and the script runs without changing anything. I think my alterations to "$_" goofs it up somehow. But I can't be sure. Just a gut feeling.

Author

Commented:
Here is the ultimate goal :
If the $ProdOrPreview variable is "A" then it reads through the file and replaces every "<DrawerName>???</DrawerName>" value with ""<DrawerName>Training</DrawerName>"

If the $ProdOrPreview variable is "b" then it reads through the file and replaces every "<DrawerName>???</DrawerName>" value with ""<DrawerName>JobName</DrawerName>"
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

$jvar = @()
$Filename = "testfile.txt"
$file2 = "tesout.txt"

write-host -foregroundcolor "yellow" "Are you switching from :"
write-host "A = Training To Prod"
write-host "B = Prod To Training"

$ProdOrPreview = read-host "Choice A or B? "
(Get-Content $Filename) | Foreach-Object {            
      $TrimmedLine=$_.trim() 
      If ($TrimmedLine.StartsWith("<JobName>")) {
            $a = $TrimmedLine -match "<\w+>(.*?)</\w+>"
            $JobName = $Matches[1]
            write-host "JobName is $JobName"
            }
      If ($TrimmedLine.StartsWith("<DrawerName>")) {
            if ($ProdOrPreview -eq 'B') {$Drawername = "Training"}
            if ($ProdOrPreview -eq 'A') {$Drawername = $JobName}
            $jvar += "<DrawerName>"+$DrawerName+"</DrawerName>`n"
            #formats line to be re-written back into test.txt
            write-host "   Writing to file $_" 
            #lets user know what got written into test.txt
            }
      } 

      $jvar | out-file $Filename

Open in new window

Author

Commented:
@BECRAIG..
i tried your code and it gets us closer. It does write the changed lines. but that is all it writes. It doesn't have all of the other data from the file.

This is what the test.txt lookslike after your script... it is missing the rest of the data.
---------------
<DrawerName>Commercial</DrawerName>

<DrawerName>Personal</DrawerName>

Author

Commented:
@BECRAIG
i am so thankful for your help.
I ran your new code and it still only writes the lines that it changes. it isn't writing the lines that it doesn't alter. I end up with a file with only two lines in it. you are on the right track. Just missing something...

Results :
<DrawerName>Training</DrawerName>
<DrawerName>Training</DrawerName>

It should look like :
<MappingJobConfiguration>
                  <JobName>Commercial</JobName>
      <LocationName />
                 <DrawerName>Training</DrawerName>
    </MappingJobConfiguration>
    <MappingJobConfiguration>
                  <JobName>Personal</JobName>
      <JobDescription>Personal</JobDescription>
      <LocationName />
                   <DrawerName>Training</DrawerName>
Top Expert 2014

Commented:
In general, here's the basic structure of the script where I've done things like this in the past:
(Get-Content $Filename) | Foreach-Object {
    If (condition)
    { $_ -replace "something","somethingelse" }
    ElseIf (othercondition)
    { $_ -replace "othersomething","othersomethingelse" }
    Else
    { $_ }
} | Out-File $Filename

Open in new window

If I get a chance this afternoon I'll modify your code unless becraig has already come up with the solution.

Author

Commented:
@footech.
your code would work but my content varies. i won't know what the find/repalce values are in advance.

Based on @BECRAIG I think my issue is I need to be doing a write-output for every line.
Right now it only does it for the one I change.
I'll modify my if statement to write the modified line if it changes, if not write the original.

Author

Commented:
@BECRAIG...
I used your idea and built a nested IF/ELSe loop that seems to be doing the trick. Let me test it a little bit and then i'll reward you the points. your "write-output" was they key I was missing.

Commented:
Try this, on line 24:
} else {$jvar += $TrimmedLine}
Here is the code that I got working thanks to @BECRAIG.
---------------------------------------------

cls
$Filename = "c:\tempxyz\test.txt"

write-host -foregroundcolor "yellow" "Are you switching from :"
write-host "A = Training To Prod"
write-host "B = Prod To Training"

$ProdOrPreview = read-host "Choice A or B? "
write-host

(Get-Content $Filename) | Foreach-Object {
	$OriginalLine = $_
	$TrimmedLine=$_.trim() #(Takes "$_" and removes the leading spaces
	If ($TrimmedLine.StartsWith("<JobName>")) {
		$a = $TrimmedLine -match "<\w+>(.*?)</\w+>"
		$JobName = $Matches[1]
		write-output "<JobName>$JobName</JobName>"
		} ELSE {
				If ($TrimmedLine.StartsWith("<DrawerName>")) {
					if ($ProdOrPreview -eq "B") {$Drawername = "Training"}
					if ($ProdOrPreview -eq "A") {$Drawername = $JobName}
					Write-Output "<DrawerName>$DrawerName</DrawerName>" #formats line to be re-written back into test.txt
					write-host "   Writing to file $_" #lets user know what got written into test.txt
				} ELSE 
						{write-output $OriginalLine} }
	} | out-file $FileName

Open in new window

Author

Commented:
OK... I'm not sure where BECRAIG's comment went, but earlier he found that I wasn't sending anytything out the pipe so I had to change my "wrtite-host" lines to "write-output". He also correctly identified that I needed to do a write-output even on lines that i don't alter. I built a nested IF/ELSE statement that does a write-output for all lines, even the ones I didn't alter.
It worked perfectly.

Commented:
Instead of modifying all the code, you could of just added the else like I said.
If you wanted to keep the spaces:
} else {$jvar += $_}
Top Expert 2014

Commented:
Yeah that was my comment about not sending to the pipeline.  Deleted it because the code I posted wasn't complete.  But I'm glad it helped you out.

Author

Commented:
OK... I'm not sure where BECRAIG's comment went, but earlier he found that I wasn't sending anytything out the pipe so I had to change my "wrtite-host" lines to "write-output". He also correctly identified that I needed to do a write-output even on lines that i don't alter. I built a nested IF/ELSE statement that does a write-output for all lines, even the ones I didn't alter.
It worked perfectly.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial