Home > Back-end >  Returning system array then using it Powershell
Returning system array then using it Powershell

Time:08-08

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:

enter image description here

If I just call the funcion, nothing else (no ForEach loop afterwards), I get:

enter image description here

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.
  • Related