Output file doesn't match Write-Host
Asked Answered
G

1

2

When I Write-Host from my .ps1 file I see:

Parentfolder >> ChildFolder

When I output to a file, I see:

ParentFolder
>>
ChildFolder

I am using a simple write-host ($childgroup.name), ">>", ($object.samaccountname)

When I try to output the same information using Return, Out-File, Export to CSV, etc... I get 3 lines for what Write-Host prints as a single line.

I just want the output file to be in the same format as the Write-Host output.

as requested:

function getchildgroups($groupname) {

    # Get initial group details and members
    $childgroup = get-adgroup $groupname -properties member

    # Only continue if this group has members
    if (($childgroup.member).count -gt 0) {

        # Loop through each member of the group
        foreach ($memberobject in $childgroup.member) {

            try {
                $object = get-adobject $memberobject -properties *;

                # If the member of the group is another group
                if ($object.objectclass -eq "group")  {

                    # Print it to the screen

                    write-host ($childgroup.name),">>", ($object.samaccountname) 
                   #$cgname = $childgroup.name
                    #$objname =$object.samaccountname
                    #Return (($cgname, ">>", $objname)) >> 
c:\Temp\NestedGroups.txt

                    # Recursive lookup the members of the sub-group (if 
not self-nested)
                    if ($memberobject -ne $object.distinguishedname) {

                        getchildgroups($object.distinguishedname);
                    }
                }
            } catch {}
        }
    }
}

# Run the function with your group name
$Groups = Get-Content C:\temp\ListOfFolders.txt
Foreach ($Group in $Groups){
getchildgroups("$group") 
}
Gleam answered 4/10, 2019 at 16:21 Comment(7)
That is incomprehensible. Please edit your question and show the content of your script as well as how you're running that script.Priory
incomprehensible??? Simple question. I get a single line with result1 >> result2 from my script when I use Write-Host. When I output it to file I get result1 on a line, >> on the next line and result2 on the third line. My question is how to get the out-put file's output to match the Write-Host output.Gleam
What have you tried, and how has what you've tried failed? Ideally, you should provide a minimal reproducible example of what you've tried, and include specific information on how it failed, with error messages and/or erroneous output. Stack Overflow is not a code-writing service; the best questions are those which provide useful information so that those who answer can guide you to devising your own correct answer. See How to Ask a Good Question.Seminal
Having trouble seeing how it could be producing different output just because of where it is piped. Are you sure the problem isn't more about how you are viewing the file? For example, you might be viewing with Notepad with word wrap turned on, or there might be invisible characters that are interpreted differently by your text editor vs. the console.Francois
I have tried: out-File, Return, Export-Csv, Transcript, Write-Output and some others to no avail.Gleam
Double checked, and no word wrap. Notepad++ is showing End Of Line characters.Gleam
Create single string if you want the output on a single line, at the moment you have three. e.g. $outputstring = $childgroup.name + ">>" + $object.samaccountname . It would however be far better if you learned how to use objects properly.Csch
A
1

Caveat:

  • Write-Host is meant for to-display output, not for outputting data - it bypasses PowerShell's success output stream (PowerShell's stdout equivalent), so that output from Write-Host cannot (directly[1]) be captured in a variable, nor redirected to file - see the bottom half of this answer for more information.

  • Use Write-Output or - preferably - PowerShell's implicit output behavior to output data, suitable for further programmatic processing.

In addition to this fundamental difference, Write-Host and Write-Output also differ in how they handle arguments:

# What Write-Host prints to the display is a *single string* that is 
# the space-separated list of the (stringification of) its arguments.
PS> Write-Host file1, '>>', file2
file1 >> file2  # printed to *display* only

# Write-Output outputs each argument - whatever its data type - *separately*
# to the success output stream.
# In the case of *string* arguments, each string renders *on its own line*.
PS> Write-Output file1, '>>', file2
file1
>>
file2

Using implicit output, the equivalent of the above Write-Output command is:

# Send an array of 3 strings to the success stream.
PS> 'file1', '>>', 'file2'
file1
>>
file2

If you redirect the Write-Output command or its implicit equivalent to a file (with > / Out-File or Set-Content[2]), you'll get the same 3-line representation.

Additionally, Write-Host performs simple .ToString() stringification on complex objects, which often results in unhelpful output; by contrast, Write-Output / implicit output uses PowerShell's rich formatting system:

# Write-Host: Unhelpful representation; entries are enumerated
#             and .ToString() is called on each.
PS> Write-Host @{ foo = 1; bar = 2 }
System.Collections.DictionaryEntry System.Collections.DictionaryEntry

# Write-Output / implicit output: rich formatting
PS> @{ foo = 1 }

Name                           Value
----                           -----
foo                            1
bar                            2

Note: If you use the Out-Host cmdlet and pipe a command to it (e.g.
@{ foo = 1; bar = 2 } | Out-Host) you do get the usual, rich output formatting that you get via Write-Output / by default - while still printing to the display only.


If you do want to output a single line as data, use a quoted string; to reference variables and embed subexpressions in a string, use an expandable string (string interpolation), "..." (see about_Quoting_Rules), or use string concatenation (+)

$arg1 = 'file1'; $arg2 = 'file2'

# Expandable string
PS> "$arg1 >> $arg2"
file1 >> file2

# String concatenation
PS> $arg1 + ' >> ' + $arg2
file1 >> file2

[1] In PowerShell v5 or higher, you can capture/redirect Write-Host output, via the information output stream, number 6; e.g.: $writeHostOutput = & { Write-Host hi } 6>&1. However, note that the information output stream is primarily designed to work with the PSv5+ Write-Information cmdlet and the common -InformationAction parameter.

[2] With strings only, > / Out-File behave the same as Set-Content, except that in Windows PowerShell a different default character applies (not in PowerShell Core). For more information about the differences, see this answer.

Alic answered 4/10, 2019 at 17:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.