- Visual Studio 2017
- .NET Core SDK
- Version driven by global.json
- Cmdlets are designed to use .NET Core 2.0 SDK with .NET Standard 2.0
- Visual Studio Code
- Experimental and optional, still need Visual Studio installed
- Install the following extensions:
- C#:
code --install-extension ms-vscode.csharp
- PowerShell:
code --install-extension ms-vscode.PowerShell
- C#:
If you plan to build with Configuration=Release which Delay Signs the build output, call
.\scripts\DisableStrongName.ps1
. Add the -Enable switch parameter to re-enable strong name verification once developing.
- PowerShell Core (6.0.0)
- Windows PowerShell v3 and up with .NET 4.7.1 or above
Driven and enforced by .editorconfig. You can learn more about this config file by reading Visual Studio documentation.
Optionally you can install the EditorConfig Visual Studio extension to give you intellisense editing the file.
Common | Common.Abstractions | ||
---|---|---|---|
Common.Authentication | |||
Common.Commands | AzureADWindowsAuthenticator | ||
Common.Api | |||
Common.Client | |||
Modules | Commands.Profile | ||
Commands.Workspaces | Commands.Reports | Commands.Data |
- Test Projects are located next to implementation (module project).
- AzureADWindowsAuthenticator has an independent dependency stack as it's compiled against .NET 4.6 (as opposed to .NET Core) to act as a bridge for ADAL on Windows (providing interactive login).
Branch | Status |
---|---|
Master | |
Dev |
Defined by appveyor.yml, see AppVeyor Docs if you need to edit.
Open PowerShell prompt and run (in repository root directory):
.\scripts\Build.ps1
# Packaging
.\scripts\Build.ps1 -Pack
# To manually test module\package output
.\scripts\PrepManualTesting.ps1 # Optionally add -Build if you haven't previously built with -Pack from command-line or Visual Studio
# You can call cmdlets after this point such as Connect-PowerBIServiceAccount, their modules get auto-imported
- Open src/PowerBIPowerShell.sln.
- Press
F6
or clickBuild
menu and selectBuild Solution
.
Binary output will be under each project's bin\$(Configuration)\$(TargetFramework)
directory (TargetFramework is typically netstandard2.0
unless its a test project then it's netcoreapp2.0
)
For Packaging, right-click on a module project and select Pack
in Visual Studio. Output is in PkgOut
folder at the root.
To test package\module, rename extension from NuGet package .nupkg
to Zip .zip
and extract archive. Load the PSD1 file in the extracted directory by using Import-Module -Path
.
This is essentially what
.\scripts\PrepManualTesting.ps1
does with the caveat it appendsPkgOut
folder to$env:PSModulePath
for your console session, when cmdlets get called their module will get auto-imported.
To execute unit tests, just open Test Explorer
and run tests from the explorer. Solution supports Live Unit Testing, there are interactive tests in the suite that are auto excluded from running with this feature.
Note: Due to some usage of .NET Framework by source code, building and executing tests have been customized and features such as run and debug test out-of-box in the IDE won't execute correctly (see workaround below).
Open Visual Studio Code by navigating to the root directory of the repository in a PowerShell (or a command prompt) window and type code .
, press Enter
. Visual Studio Code should open with POWERBI-POWERSHELL
in the Explorer pane. Settings, configurations, and tasks are auto-loaded by the files in the .vscode
directory.
To build, first-time run task Restore
by pressing Ctrl+P
, type task Restore
, press Enter
.
After restoring packages you can execute build by pressing Ctrl+Shift+B
.
To run tests, highlight the name of the test with your cursor and press Ctrl+P
, type task DebugTest
, press Enter
. If you don't want to build do task DebugTest (No Build)
instead. Set your breakpoint in the test and press F5
to start debugging by picking the dotnet process ID shown from DebugTest
. Press F5
once more to trigger the breakpoint.
- Create a new class in a Module project.
- Either extend
PowerBIClientCmdlet
fromMicrosoft.PowerBI.Common.Client
project or extendPowerBICmdlet
fromMicrosoft.PowerBI.Commands.Common
project if a client is not needed. - Implement class and optionally add other interfaces from
Microsoft.PowerBI.Common.Abstractions
for common parameters. - Add
[Cmdlet(CmdletVerb, CmdletName)]
attribute to class and providepublic const string
forCmdletVerb
andCmdletName
.- For
CmdletVerb
, pick from the System.Management.Automation.Verbs* classes.
- For
- Optionally add
[OutputType(typeof(type))]
if your Cmdlet class writes an object to the output stream. - Optionally add
[Alias("Get-Alias1", "Get-Alias2")]
to your Cmdlet class. - Update PowerShell manifest file (*.ps1), add the new cmdlet to
CmdletsToExport
and if you added an alias updateAliasesToExport
too. - Add a test class to verify your cmdlet by adding (replacing with your new class name):
using (var ps = System.Management.Automation.PowerShell.Create())
{
ProfileTestUtilities.ConnectToPowerBI(ps); // If login is needed
ps.AddCommand(new CmdletInfo($"{<class name>.CmdletVerb}-{<class name>.CmdletName}", typeof(<class name>))); // Optionally .AddParameter(), use intellisense to see options
var result = ps.Invoke();
// Add asserts to verify
TestUtilities.AssertNoCmdletErrors(ps);
}
- If your test is interactive, add method attributes
[TestCategory("Interactive")]
and[TestCategory("SkipWhenLiveUnitTesting")]
(last tells Live Unit Testing to skip it). - Run test to verify cmdlet is being called correctly.
- Add parameters to cmdlet class and implement cmdlet logic in
ExecuteCmdlet()
method.
- Open PowerShell and set your current directory to the root of this repository.
- In PowerShell, execute the following by supplying your module name:
$moduleName = '<fill out with module name>'
$root = "$pwd"
cd .\src\Modules
mkdir $moduleName
cd ".\$moduleName"
dotnet new classlib --name "Commands.$moduleName" --framework netstandard2.0
dotnet new mstest --name "Commands.$moduleName.Test"
cd ".\Commands.$moduleName"
dotnet add package PowerShellStandard.Library --version 3.0.0-preview-01
dotnet add reference "$root\src\Common\Commands.Common\Commands.Common.csproj"
dotnet add reference "$root\src\Common\Common.Abstractions\Common.Abstractions.csproj"
dotnet add reference "$root\src\Common\Common.Client\Common.Client.csproj"
dotnet add reference "$root\src\Modules\Profile\Commands.Profile\Commands.Profile.csproj"
Remove-Item .\Class1.cs
New-ModuleManifest -Path ".\MicrosoftPowerBIMgmt.$moduleName.psd1" `
-Author 'Microsoft Corporation' `
-CompanyName 'Microsoft Corporation' `
-Copyright 'Microsoft Corporation. All rights reserved.' `
-RootModule "Microsoft.PowerBI.Commands.$moduleName.dll" `
-ModuleVersion '1.0.0' `
-Description "Microsoft Power BI PowerShell - $moduleName cmdlets for Microsoft Power BI" `
-PowerShellVersion '3.0' `
-PrivateData @{
PSData=@{
Tags=@('PowerBI', $moduleName)
ProjectUri='https://github.com/Microsoft/powerbi-powershell'
}
}
- Edit CSProj file in the current directory and add (update with your module name):
<PropertyGroup>
<AssemblyName>Microsoft.PowerBI.Commands.<fill out with module name></AssemblyName>
<RootNamespace>Microsoft.PowerBI.Commands.<fill out with module name></RootNamespace>
<ReferenceWindowsAuthenticator>true</ReferenceWindowsAuthenticator>
</PropertyGroup>
<!-- NuGet Package Properties -->
<PropertyGroup>
<IsPackable>true</IsPackable>
<PackageId>MicrosoftPowerBIMgmt.<fill out with module name></PackageId>
<Description>Microsoft Power BI PowerShell - <fill out with module name> cmdlets for Microsoft Power BI</Description>
<PackageTags>PowerBI;<fill out with module name></PackageTags>
</PropertyGroup>
- In the same CSProj file, for any packages add
<PrivateAssets>All</PrivateAssets>
inside<PackageReference></PackageReference>
as this will prevent those packages becoming dependencies for the module. - In the same CSProj file, for any project references outside of the Modules folder (such as Commands.Common and Commands.Abstractions, but don't do it for Commands.Profile), add
<PrivateAssets>All</PrivateAssets>
inside<ProjectReference></ProjectReference>
. - Save the CSProj file and close.
- Execute in PowerShell (same console window as before):
cd "..\Commands.$moduleName.Test"
dotnet add package PowerShellStandard.Library --version 3.0.0-preview-01
dotnet add package Microsoft.PowerShell.SDK --version 6.0.1
dotnet add package Microsoft.PowerShell.Commands.Diagnostics --version 6.0.1
dotnet add package Microsoft.WSMan.Management --version 6.0.1
dotnet add reference "$root\src\Common\Commands.Common.Test\Commands.Common.Test.csproj"
dotnet add reference "$root\src\Common\Commands.Common\Commands.Common.csproj"
dotnet add reference "$root\src\Common\Common.Abstractions\Common.Abstractions.csproj"
dotnet add reference "$root\src\Common\Common.Authentication\Common.Authentication.csproj"
dotnet add reference "$root\src\Common\Common.Client\Common.Client.csproj"
dotnet add reference "$root\src\Modules\Profile\Commands.Profile.Test\Commands.Profile.Test.csproj"
dotnet add reference "$root\src\Modules\Profile\Commands.Profile\Commands.Profile.csproj"
dotnet add reference "$root\src\Modules\$moduleName\Commands.$moduleName\Commands.$moduleName.csproj"
- Edit CSProj file in the current directory and add (update with your module name):
<PropertyGroup>
<AssemblyName>Microsoft.PowerBI.Commands.<fill out with module name>.Test</AssemblyName>
<RootNamespace>Microsoft.PowerBI.Commands.<fill out with module name>.Test</RootNamespace>
<ReferenceWindowsAuthenticator>true</ReferenceWindowsAuthenticator>
</PropertyGroup>
- Execute in PowerShell (same console window as before):
cd $root
cd .\src
dotnet sln add "$root\src\Modules\$moduleName\Commands.$moduleName\Commands.$moduleName.csproj"
dotnet sln add "$root\src\Modules\$moduleName\Commands.$moduleName.Test\Commands.$moduleName.Test.csproj"
ii .\PowerBIPowerShell.sln
- Visual Studio should open for you, add a new class to your module project.
- Make the class public and extend PowerBICmdlet (
Ctrl+.
to add using statement and implement) - Decorate class
[Cmdlet(CmdletVerb, CmdletName)]
and defineCmdletVerb
andCmdletName
aspublic const string
(for verb use the System.Management.Automation.Verbs* classes to pick an approved verb, you can see in the list in PowerShell by doing Get-Verb). - Optionally add
[OutputType(typeof(type))]
to your class if you cmdlet returns a certain output. - Click on psd1 file in the module project, change Build Action to
Content
, edit csproj and add the following to the psd1 file<Content>
element:
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
If the content extension is not .psd1
or .types.ps1xml
then add the following to the Content
element too:
<Pack>true</Pack>
<PackagePath></PackagePath>
- Save the project file and build the solution.
- A
help
folder should appear under your project after you build, the files contain the documenation for your module and cmdlets which you can fill out.
Note: The PowerShell Manifest file (*.psd1) might get its encoding messed up when pushing and pulling from Git. After pushing changes to Git, pull down changes and verify encoding looks correct. This issue may be fixed in PowerShell Core with PR 2048.