Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
command-line-simple-example.md232 linesDownload Raw Back to cmdlet-example
1# Creating a cross-platform binary module with the .NET Core command-line interface tools2 3This example uses the [.NET Core command-line interface tools][dotnet-cli] (aka4`dotnet` CLI) to demonstrate how to create a binary module that is portable across operating5systems supported by **PowerShell Core** as well as **Windows PowerShell** version 3 and higher.6 7Because the binary module's assembly will be created as a .NET Standard 2.0 class library,8the same assembly can be imported into both PowerShell Core and Windows PowerShell.9This means you do not have to build and distribute separate assemblies that target these two10different implementations of PowerShell.11 12## Prerequisites13 14* PowerShell Core and/or Windows PowerShell15 16  For this example, you can use any operating system that is supported by PowerShell Core.17  To see if your operating system is supported and to get instructions on how to install18  PowerShell Core on your operating system, see the [Get PowerShell][pscore-os] topic in19  the PowerShell repo's [README.md][readme] file.20 21  Note: On Windows 10 Anniversary Update or higher, you can use the [Windows Subsystem for22  Linux][wsl] (WSL) console to build the module. In order to import and use the module, you'll need23  to install PowerShell Core for the distribution and version of Linux you're running.24  You can get that version info by running the command `lsb_release -a` from the WSL console.25 26* .NET Core 2.x SDK27 28  Download and install the [.NET Core 2.x SDK][net-core-sdk] for your operating system.29  It is recommended that you use a package manager to install the SDK on Linux.30  See these [instructions][linux-install] on how to install the SDK on Linux.31  Be sure to pick your distribution of Linux e.g. RHEL, Debian, etc to get the32  appropriate instructions for your platform.33 34## Create the .NET Standard 2.0 Binary Module35 361. Verify you are running the 2.0.0 version of the `dotnet` CLI.37 38   ```powershell39   dotnet --version40   ```41 42   This should output `2.0.0` or higher. If it returns a major version of 1, make sure you have43   installed the .NET Core 2.x SDK and have restarted your shell to get the newer version of44   the SDK tools.45 461. Use the `dotnet` CLI to create a starter `classlib` project based on .NET Standard 2.047   (the default for classlib projects).48 49   ```powershell50   dotnet new classlib --name MyModule51   ```52 531. Add a `global.json` file that specifies that the project requires the `2.0.0` version of54   the .NET Core SDK.  This is necessary to prevent issues if you have more than one55   version of the .NET Core SDK installed.56 57   ```powershell58   cd MyModule59   dotnet new globaljson --sdk-version 2.0.060   ```61 621. Add the [PowerShell Standard Library][ps-stdlib] package to the project file.63   This package provides the `System.Management.Automation` assembly.64 65   Note: As newer versions of this library are released, update the version number66   in this command to match the latest version.67 68   ```powershell69   dotnet add package PowerShellStandard.Library --version 3.0.0-preview-0170   ```71 721. Add source code for a simple PowerShell command to the `Class1.cs` file by opening73   that file in an editor and replacing the existing code with the following code.74 75   ```csharp76   using System;77   using System.Management.Automation;78 79   namespace MyModule80   {81       [Cmdlet(VerbsCommunications.Write, "TimestampedMessage")]82       public class WriteTimestampedMessageCommand : PSCmdlet83       {84           [Parameter(Position=1)]85           public string Message { get; set; } = string.Empty;86 87           protected override void EndProcessing()88           {89               string timestamp = DateTime.Now.ToString("u");90               this.WriteObject($"[{timestamp}] - {this.Message}");91               base.EndProcessing();92           }93       }94   }95   ```96 971. Build the project.98 99   ```powershell100   dotnet build101   ```102 1031. Import the binary module and invoke the new command.104 105   Note: The previous steps could have been performed in a different shell such as106   Bash if you're on Linux.  For this step, make sure you are running PowerShell Core.107 108   ```powershell109   cd 'bin/Debug/netstandard2.0'110   Import-Module ./MyModule.dll111   Write-TimestampedMessage "Test message."112   ```113 114## Using a .NET Standard 2.0 based binary module in Windows PowerShell115 116You may have heard that a .NET assembly compiled as a .NET Standard 2.0 class library117will load into both .NET Core 2.x applications such as PowerShell Core and118.NET Framework 4.6.1 (or higher) applications such as Windows PowerShell.119This allows you to build a single, cross-platform binary module.120 121Unfortunately, this works best when the .NET Framework application, in this case122Windows PowerShell, has either been compiled against a .NET Standard 2.0 library or with123support declared for .NET Standard libraries.  In which case, the build system can provide the124appropriate binding redirects and facade and shim assemblies so that the .NET Standard 2.0125library can find the .NET Framework types it needs within the context of the running126application.127 128Fortunately, this has been fixed in .NET Framework 4.7.1 and in the Windows 10 Fall129Creators Update. This version of the .NET Framework allows existing applications to130"just work" without the need to modify and/or re-compile them. On these systems, a131.NET Standard 2.0 based binary module will work in Windows PowerShell.132 133However, for Windows systems that have not been updated to .NET Framework 4.7.1 such a134binary module will not run correctly in Windows PowerShell.135 136Let's see what happens when you attempt to use this module in **Windows PowerShell** on137Windows 10 CU (1703 or lower) without .NET Framework 4.7.1 installed.138 1391. Copy `MyModule.dll` to a folder on a Windows machine.140 1411. Import the module.142 143   ```powershell144   Import-Module .\MyModule.dll145   ```146 147   Note: The module should import without errors.148 1491. Execute the `Write-TimestampedMessage` command.150 151   ```powershell152   Write-TimestampedMessage "Test message."153   ```154 155   This will result in the following error:156 157   ```text158   Write-TimestampedMessage : Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral,159   PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.160   At line:1 char:1161   + Write-TimestampedMessage "Test message."162   + ~~~~~~~~~~~~~~~~~~~~~~~~163       + CategoryInfo          : NotSpecified: (:) [], FileNotFoundException164       + FullyQualifiedErrorId : System.IO.FileNotFoundException165   ```166 167If the command worked, congratulations! Your system was probably updated to168.NET Framework 4.7.1.  Otherwise, this error indicates that the `MyModule.dll` assembly169can't find the `netstandard.dll` "implementation" assembly for the version of the170.NET Framework that Windows PowerShell is using.171 172### The fix for missing netstandard.dll173 174If you install (or already have) the .NET Core SDK for Windows, you can175find the `netstandard.dll` implementation assembly for .NET 4.6.1 in the following directory:176`C:\Program Files\dotnet\sdk\<version-number>\Microsoft\Microsoft.NET.Build.Extensions\net461\lib`.177Note that, the version number in the path may vary depending on the installed SDK.178 179If you copy `netstandard.dll` from this directory to the directory containing180`MyModule.dll`, the `Write-TimestampedMessage` command will work.  Let's try that.181 1821. Install [.NET Core SDK for Windows][net-core-sdk], if it isn't already installed.183 1841. Start a new Windows PowerShell console. Remember that once a binary assembly is185   loaded into PowerShell it can't be unloaded. Restarting PowerShell is necessary to186   get it to reload `MyModule.dll`.187 1881. Copy the `netstandard.dll` implementation assembly for .NET 4.6.1 to the module's directory.189 190   ```powershell191   cd 'path-to-where-you-copied-module.dll'192   Copy-Item 'C:\Program Files\dotnet\sdk\<version-number>\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll' .193   ```194 1951. Import the module and execute the command:196 197   ```powershell198   Import-Module .\MyModule.dll199   Write-TimestampedMessage "Test message."200   ```201 202   Now the command should succeed.203 204   Note: If it fails, restart Windows PowerShell to make sure205   you don't have a previously loaded version of the assembly in the session and repeat206   step 4.207 208If you use additional libraries there may be more work involved. This approach has209been successfully tested using types from `System.Xml` and `System.Web`.210 211## Wrap-up212 213In a few steps, we have built a PowerShell binary module using a .NET Standard 2.0214class library that will run in PowerShell Core on multiple operating systems.215It will also run in Windows PowerShell on Windows systems that have been updated to216.NET Framework 4.7.1 as well as the Windows 10 Fall Creators Update which comes with that217version pre-installed.  Furthermore, this binary module can be built on Linux218and macOS as well as Windows using the .NET Core 2.x SDK command-line tools.219 220For more information on .NET Standard, check out the [documentation][net-std-docs]221and the [.NET Standard YouTube channel][net-std-chan].222 223[dotnet-cli]:    https://learn.microsoft.com/dotnet/core/tools/224[net-core-sdk]:  https://www.microsoft.com/net/download/core225[net-std-docs]:  https://learn.microsoft.com/dotnet/standard/net-standard226[net-std-chan]:  https://www.youtube.com/playlist?list=PLRAdsfhKI4OWx321A_pr-7HhRNk7wOLLY227[pscore-os]:     https://github.com/powershell/powershell#get-powershell228[readme]:        ../../README.md229[linux-install]: https://www.microsoft.com/net/core#linuxubuntu230[ps-stdlib]:     https://www.nuget.org/packages/PowerShellStandard.Library/231[wsl]:           https://msdn.microsoft.com/commandline/wsl/about232