I have the following function that gets a list of folder names and displays the results in a tabular fashion. Once that is done, I want to iterate through that list to do different things depending on the situation. Thus, the need to have a function so I don't have to repeat the code for every situation. The function:
Function Show-UsersFolders{
# Get list of folders where file is to be copied
$listOfFolders = Get-ChildItem -Directory | Select-Object Name
# Display total folders and display them in tabular form (8 columns)
Write-Host ("`nFound: " $listOfFolders.Count " users folders.")
$listOfFolders | Format-Wide -Column 8
, $listOfFolders
}
$myList = Show-UsersFolders
ForEach ($folder in $myList) {
Write-Host $folder
}
I get the following:
If I just call the funcion, nothing else (no ForEach loop afterwards), I get:
How do I go about printing the results and returning them so I can iterate through them later? I've read about how Powershell returns "everything", but I can't just make sense out of it so I can work with it.
Any help would be greatly appreciated.
Thanks in advance!
CodePudding user response:
If I got it right you don't actually need a function in such a case. It should be enough to save the output of Get-ChildItem
in a variable like this:
$UserFolderList = Get-ChildItem -Path 'C:\Users' -Directory
Now you can do all sorts of actions with the folder list ... like outputting the count of the elements ...
$UserFolderList.Count
... or like outputting only a few selcted properties of the folders in the folder list ...
$UserFolderList |
Select-Object -Property Name, FullName
... or even running further actions on each individual folder in the folder list ...
foreach ($UserFolder in $UserFolderList) {
"Name of the folder: '$($UserFolder.name)' - full path of the folder: '$($UserFolder)'"
}
And because you did not limit yourself to a particular property with a Select-Object
in the first place you can still access all the properties a folder has ... and you can do this again and again with the variable. ;-)
$UserFolderList |
Select-Object -Property Name, LastAccessTime
and of course you can still format the output as you like ...
$UserFolderList |
Select-Object -Property Name |
Format-Wide
CodePudding user response:
As zett42 points out, even though the purpose of Format-*
cmdlets is to format objects for display, their output - in the form of objects providing formatting instructions - is still sent to the success output stream (which is the stream whose output is sent through the pipeline, captured in a variable, or redirected with >
) rather than directly to the host (display).
You can use the Out-Host
cmdlet to explicitly request that those processing instructions be interpreted and rendered to the host - as they would be by default - independently of the success output stream.
- By contrast, when
Write-Host
renders objects to the host (display), it performs simple.ToString()
rendering, which with complex objects typically results in unhelpful representations - see this answer for more information.
You can combine Out-Host
with the common -OutVariable
(-ov
) parameter in order to both:
- print a command's output objects' formatted representation to the host (display) via
Out-Host
- and also capture the output objects as-is in a target variable, via
-OutVariable
# * Prints a formatted representation of the .Name property values,
# via Format-Wide and Out-Host, directly to the host (display).
# * Also captures the command output in variable $listOfFolders, via
# the common -OutVariable parameter. Note that the target variable,
# $listOfFolders, must be specified WITHOUT "$"
Get-ChildItem -Directory -OutVariable listOfFolders |
Format-Wide -Column 8 -Property Name |
Out-Host
# $listOfFolders now contains an array [list] of [System.IO.DirectoryInfo]
# instances, which you can process as needed.