简体   繁体   中英

What is wrong with this powershell script that iterates a List? Foreach-Object -Process { Set-Alias ... }

I have got a module that returns a List of LinuxAlias (class I made)

When I try to iterate them to Set-Alias in my session I am having troubles.

Data: MyModule has the Get-LinuxAliases command. Get-LinuxAliases command is a binary module that returns a List of LinuxAlias.

Output definition:

[OutputType(typeof(List<LinuxAlias>))]

LinuxAlias definition:

public class LinuxAlias
    {
        public String Name { get; set; }
        public String RawCommand { get; set; }

        public String Value { get; set; }
        public String TranslatedPowershellCommand { get; set; }
        public class COMMENT_BLOCK_EXCEPTION : Exception
        {
        }
        public class EMPTY_LINE_EXCEPTION : Exception
        {
        }
        public class UNRECOGNIZED_INPUT : Exception
        {
        }
    }

I do:

if ( Get-Module "MyModule" ) {
    Get-LinuxAliases | ForEach-Object -Process { 
        try {
            [string]$name = $_.Name;
            [string]$val = $_.Value;
                Set-Alias -Name $name -Value $val -Force;
        }
        catch {
            Write-Warning $_.Exception.GetType().FullName;
        }

    }
}

What is the expected behaviour? Since I noticed, for example. If I just Write-Host $_.Name and Write-Host $_.Value for each iteration. It first will write names and then values, having something like:

name1 name2 ... value1 value2 ...

What is not the expected behaviour in a For-Each iterator I guess. It should be:

name1 value1 name2 value2

(Get-LinuxAliases) [0] returned :

Name RawCommand Value TranslatedPowershellCommand
---- ---------- ----- ---------------------------
cls  'clear'    clear

Someone could bring me light to this scenario?

Thanks in advance.

that returns a List of LinuxAlias.

Generally, except in special circumstances, cmdlets :

  • should not output instances of a collection type (such as List in your case).
  • instead should output multiple objects to the pipeline one by one .

The reason is that other cmdlets - such as ForEach-Object - expect other commands to produce output object by object .

Get-LinuxAliases | ForEach-Object -Process { ...

With your current design, ForEach-Object receives a single input object that is the list as a whole , which is not your intent.

Therefore:

  • Make your cmdlet-implementing class indicate that it returns LinuxAlias , not a list of it; that multiple instances of that type may be returned is invariably implied in PowerShell.

     [OutputType(typeof(LinuxAlias)]
  • To produce output from your cmdlet, use WriteObject(list, true) , ie, use the WriteObject overload that enumerates collections ; that is, make it send the LinuxAlias instances stored in your List instance to the pipeline one by one .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM