Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell attributes?

is it possible to assign some metadata Attributes to powershell macros? I have the set of macros and I want to encapsulate them to logical groups. I imagine something like:

[UnitTest]
function Do-Something()
{
...
}

and then pass all loaded macros in runtime and filter them out like:

$macrosInRuntime = Get-Item function: 
$unitTestMacros = $macrosInRuntime | 
    ? {$_.Attributes -contain "UnitTest"} # <-- ???
foreach ($macro in $unitTestMacros)
{
   ....
}

I will be greatful for any help

like image 249
Tomas Panik Avatar asked Jan 11 '11 14:01

Tomas Panik


People also ask

How do I get attributes in PowerShell?

To get the properties of an object, use the Get-Member cmdlet. For example, to get the properties of a FileInfo object, use the Get-ChildItem cmdlet to get the FileInfo object that represents a file. Then, use a pipeline operator ( | ) to send the FileInfo object to Get-Member .

What does %% mean in PowerShell?

% is an alias for the ForEach-Object cmdlet. An alias is just another name by which you can reference a cmdlet or function.

How do I see all properties in PowerShell?

To display ALL of the properties, we need to use the -Property parameter with a wildcard value. You see below sixteen properties are displayed, even if they have null values. This approach is helpful when you exploring results and are looking for properties of interest.

Why we use $_ in PowerShell?

$_ is a variable created by the system usually inside block expressions that are referenced by cmdlets that are used with pipe such as Where-Object and ForEach-Object . But it can be used also in other types of expressions, for example with Select-Object combined with expression properties.


2 Answers

Interesting question... There are no such attributes of functions, AFAIK. But I think there is a half-hacky way that uses comment-based help attributes (perhaps not even hacky at all but I am not quite sure).

<#
.FUNCTIONALITY
    TEST1
#>
function Do-Something1
{}

<#
.FUNCTIONALITY
    TEST2
#>
function Do-Something2
{}

Get-ChildItem Function: | %{
    $fun = $_.Name
    try {
        Get-Help $fun -Functionality TEST* | %{
            switch($_.Functionality) {
                'TEST1' { "$fun is for test 1" }
                'TEST2' { "$fun is for test 2" }
            }
        }
    }
    catch {}
}

Output:

Do-Something1 is for test 1
Do-Something2 is for test 2

Perhaps this approach might be useful in some scenarios.

See also the section COMMENT-BASED HELP KEYWORDS in help:

man about_Comment_Based_Help

UPDATE Though the answer above is accepted, I am still not quite happy with it. Here is yet another approach that is definitely not hacky. It also has an advantage, see the comments. This approach uses extra aliases with conventional names.

# Functions to be used in tests, with any names
function Do-Something1 { "Something1..." }
function Do-Something2 { "Something2..." }

# Aliases that define tests, conventional names are UnitTest-*.
# Note: one advantage is that an alias can be defined anywhere,
# right where a function is defined or somewhere else. The latter
# is suitable in scenarios when we cannot modify the source files
# (or just do not want to).
Set-Alias UnitTest-Do-Something1 Do-Something1
Set-Alias UnitTest-Do-Something2 Do-Something2

# Get UnitTest-* aliases and extract function names for tests.
Get-Alias UnitTest-* | Select-Object -ExpandProperty Definition

# Or we can just invoke aliases themselves.
Get-Alias UnitTest-* | % { & $_}
like image 111
Roman Kuzmin Avatar answered Oct 07 '22 01:10

Roman Kuzmin


Organizing and grouping commands is an ongoing dilemma in PowerShell. It is something that will always have to be managed. However, there are some best practices around naming cmdlets and functions that can work if you are diligent. You probably have noticed that all cmdlets are in the verb-noun format. IE Get-Process, Set-Item, etc. What a lot of people do is add a third part to the command which groups the nouns together. For example, in the world of Active Directory, you don't have get-user, but rather get-aduser.

One thing you could do, and it may not be the prettiest thing, is to name your unit test functions with some 2 or 3 letter sequence of your choosing. Let's say you chose something incredibly original like UT for unit test. Your function would then be

function Do-UTSomething { "Something was done" }

Once you have all your UT functions, you can use the Get-Command cmdlet to iterate through them like so

Get-Command *UT* -commandtype function

Also, if you go a bit further and package them into a module, you could do one better and sort by that module.

Get-Command -module MyUnitTest

You can get all kinds of information on modules by using

help about_modules
like image 34
Andy Schneider Avatar answered Oct 07 '22 00:10

Andy Schneider