Avatar of JasonLattin
JasonLattin
 asked on

Powershell "out-file" command write blank file.

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>
PowershellScripting LanguagesXML

Avatar of undefined
Last Comment
JasonLattin

8/22/2022 - Mon
SOLUTION
becraig

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
JasonLattin

ASKER
@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.
JasonLattin

ASKER
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>"
becraig

$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

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
JasonLattin

ASKER
@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>
JasonLattin

ASKER
@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>
footech

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.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
JasonLattin

ASKER
@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.
JasonLattin

ASKER
@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.
Dan Craciun

Try this, on line 24:
} else {$jvar += $TrimmedLine}
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
ASKER CERTIFIED SOLUTION
JasonLattin

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
JasonLattin

ASKER
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.
Dan Craciun

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 += $_}
footech

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.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
JasonLattin

ASKER
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.