Is there a better way to do this loop -- trying to learn

Hi, a few weeks ago I came across a question on Facebook that to me have no practical usage at the moment but it gave me a chance to try to solve it. (For those who don’t bother to check the link,) the question was " 1. Create a loop to $count all of the results for “get-help -name about*,
2. for each result assign a number corresponding to my loop, and
3. Somehow I plan to use Outfile to dump the contents of all $Name.count to my directory.”

After a lot of reading and failing I came up with this

# Get the files into the variable 
$list = get-help about_* -Full 
# Takes each object in the $list-variable, creates a new file with the same name and adds content.
foreach ( $help in $list ) {
    Out-File -FilePath "C:\temp\About\$($help.Name).txt" 
    Set-Content "C:\temp\About\$($help.Name).txt" -Value $help
} 

So in lack of feedback on Facebook, my question is if this could be solved in a different way and / or better way.
New to scripting so trying to learn

kjetil

kjetil,
Welcome to the forum. :wave:t4:

Of course. What’s wrong with yours? :wink:

That’s a matter of opinion. Define better! :wink:

You may start with reading a little more about loops:

2 Likes

It works so nothing wrong, just looking for guidance and maybe see other ways to solve it :grinning:

Will go through the links you provided!

kjetil

@kjetil - I’ll echo your post a week ago to the OP on Facebook in that I did not understand what he intended as output. For starters, $Name.Count is a very specific action as it calls the Count method on variable Name.

Did he want an integer value that represents the current count of all the help entries‽ I don’t think that’s what he intended when looking at his script.

Tagging onto this, you stated that you were looking for a better way and other ways to solve it. Therefore, given uncertainty and freedom, the following won’t answer the FB post exactly. But it may come close.

1. Create a loop to $count all of the results for "get-help -name about*

No loop is required to count the help files.

(Get-Help -Name "about_*").Count;

2. for each result assign a number corresponding to my loop

Okay… Odd, but let’s use with a for loop (h/t @Olaf for the link) to create a surrogate key (identity value) for each result. I might draw some heat for using a Class—but I love 'em for the blueprinting and there are benefits to typing and naming the properties.

The metadata returned here is the same as his script. However, I’m cutting it down to the identity (_id) and the help file (Name) name due to sparsity in the other fields. Synopsis could be added in future as text file content, but that’s not indicated by the OP.

Class HelpFile
{
    [int] $_id;
    [string] $Name;

# A ctor isn't necessary, but this is a tiny load.
    HelpFile($q1,$q2)
    {
        $this._id = $q1;
        $this.Name = $q2;
    }
}

$x = (Get-Help -Name "about_*").Name;
$z = [ArrayList]::new();

for ($i = 0; $i -lt $x.Count; $i++)
{
    $y = [HelpFile]::new($i+1,$x[$i]);
    [void]$z.Add($y);
}

I could use a Hash table and a PSObject, but I tend to avoid them and the += operator in favor of ArrayLists and Add(). Having a Class ctor and methods is handy for when data get funky.

3. Somehow I plan to use Outfile to dump the contents of all $Name.count to my directory

The OP’s script ( Out-File -PSPath "C:\Users\smoov\Desktop\Powershell Help\$($Name.Name).txt" ) should result in 100+ empty text files as no content is passed into the named text file. This agrees with his observation. Setting that aside, let’s just dump the contents of $z into one text file.

$z|Out-File "A:\HelpFiles.txt"
ii "A:\HelpFiles.txt";

Remarks

_id is something I picked up from BSON. Coincidentally…

$z|ConvertTo-Json|Out-File "A:\box\HelpFiles.json"
ii "A:\box\HelpFiles.json";

1 Like

Thank you for a long and good answer. It’s above my current understanding at the moment, but I will save it and come back to when I get more understanding of PowerShell :grinning:

I see from my notes that the counting part I came up with was

Get-help about* | Select-Object "name" | ForEach-Object { $Name = 0 } { ($_.name) + " " + ($name = $Name + 1) } { Write-Host "There are" $Name "about_ files" }  

but never finished it. Your solution is a lot better looking :grinning:

1 Like

Hey @Olaf, I just finished the two articles and I really wish I had found them some time ago when I struggled with a problem and didn’t understand the for loop at all. Thank you!