2

I have created a PowerShell cmdlet in C#:

using System.Management.Automation;
using thosepeskyexternalclasses

[Cmdlet(VerbsCommon.Get, "GetActivity", SupportsTransactions = false)]
public class GetActivity : PSCmdlet
{
    protected override void ProcessRecord()
    {
        base.ProcessRecord();
        // Get the activities
        List<activity> activities = GetActivities();

        WriteObject(activities);

    }
}

The activity object does not contain a name property so when it is returned and displayed it is using the ID Value. This can be resolved by using the following command:

Update-TypeData -TypeName activity -DefaultDisplayProperty otherprop

This has to be done every time I start a new PowerShell session. Is there a way to do the equivalent function when my extension module is loaded?

2
  • 2
    The conventional approach is to package your binary module as a directory-based module with a manifest, and bundle a *.Types.ps1xml type-extension file with it. Commented Aug 6, 2024 at 19:31
  • 1
    I followed this guidance and have successfully solved my use case. Thanks! Commented Aug 7, 2024 at 13:55

1 Answer 1

0

You can add a static ctor to your cmdlet where you can invoke Update-TypeData using a PowerShell instance:

using System.Collections.Generic;
using System.Management.Automation;
using thosepeskyexternalclasses;

[Cmdlet(VerbsCommon.Get, "Activity", SupportsTransactions = false)]
public sealed class GetActivity : PSCmdlet
{
    static GetActivity()
    {
        // set the `DefaultDisplayProperty` for the `activity` type the first time this cmdlet is called
        using PowerShell powershell = PowerShell.Create(RunspaceMode.CurrentRunspace);
        powershell
            .AddCommand("Update-TypeData")
            .AddParameters(new Dictionary<string, string>
            {
                ["TypeName"] = "thosepeskyexternalclasses.activity",
                ["DefaultDisplayProperty"] = "otherprop" // <- update with actual property name!
            })
            .Invoke();
    }

    protected override void ProcessRecord()
    {
        // Get the activities
        List<activity> activities = GetActivities();
        WriteObject(activities);
    }
}

As mklement0 states in a comment, another option considering this cmdlet could be part of a binary module, best practice would be to have a *.Types.ps1xml file where you define the default display property. Then you add this file's path to TypesToProcess of your Module Manifest.

For this specific example, the XML would be something like:

<?xml version="1.0" encoding="utf-8"?>
<Types>
  <Type>
    <Name>thosepeskyexternalclasses.activity</Name>
    <Members>
      <MemberSet>
        <Name>PSStandardMembers</Name>
        <Members>
          <NoteProperty>
            <Name>DefaultDisplayProperty</Name>
            <!-- update with actual property name here -->
            <Value>otherprop</Value>
          </NoteProperty>
        </Members>
      </MemberSet>
    </Members>
  </Type>
</Types>
Sign up to request clarification or add additional context in comments.

2 Comments

@mklement0 thanks for the +1 and np, was worth the research there are absolutely 0 examples in google reg. DefaultDisplayProperty, only for DefaultDisplayPropertySet. maybe worth submitting an issue to the docs repo to add an example
Thanks for the guidance. Both of the described methods resolved the issue. I have created a Module Manifest as it seems like best practice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.