diff --git a/Commands/Admin/GetTenantSite.cs b/Commands/Admin/GetTenantSite.cs index 5e60574c1..dc2039d3b 100644 --- a/Commands/Admin/GetTenantSite.cs +++ b/Commands/Admin/GetTenantSite.cs @@ -11,7 +11,7 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Get, "PnPTenantSite", SupportsShouldProcess = true)] - [CmdletHelp(@"Uses the tenant API to retrieve site information.", + [CmdletHelp(@"Retrieve site information.", "Use this cmdlet to retrieve site information from your tenant administration.", Category = CmdletHelpCategory.TenantAdmin, SupportedPlatform = CmdletSupportedPlatform.Online, OutputType = typeof(Microsoft.Online.SharePoint.TenantAdministration.SiteProperties), diff --git a/Commands/Admin/GetTimeZoneId.cs b/Commands/Admin/GetTimeZoneId.cs index db0018199..9cf0d4e18 100644 --- a/Commands/Admin/GetTimeZoneId.cs +++ b/Commands/Admin/GetTimeZoneId.cs @@ -8,6 +8,7 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Get, "PnPTimeZoneId")] [CmdletHelp("Returns a time zone ID", + "In order to create a new classic site you need to specify the timezone this site will use. Use the cmdlet to retrieve a list of possible values.", Category = CmdletHelpCategory.TenantAdmin, OutputType = typeof(IEnumerable), OutputTypeDescription = diff --git a/Commands/Admin/GetWebTemplates.cs b/Commands/Admin/GetWebTemplates.cs index 146bf9cd9..ddd6635aa 100644 --- a/Commands/Admin/GetWebTemplates.cs +++ b/Commands/Admin/GetWebTemplates.cs @@ -8,6 +8,7 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Get, "PnPWebTemplates")] [CmdletHelp(@"Returns the available web templates.", + "Will list all available templates one can use to create a classic site.", Category = CmdletHelpCategory.TenantAdmin, SupportedPlatform = CmdletSupportedPlatform.Online, OutputType =typeof(Microsoft.Online.SharePoint.TenantAdministration.SPOTenantWebTemplateCollection), diff --git a/Commands/Admin/NewSite.cs b/Commands/Admin/NewSite.cs index 63377b42d..7fab5bd3c 100644 --- a/Commands/Admin/NewSite.cs +++ b/Commands/Admin/NewSite.cs @@ -15,9 +15,9 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.New, "PnPSite")] [CmdletHelp("BETA: This cmdlet is using early release APIs. Notice that functionality and parameters can change. Creates a new site collection", + "The New-PnPSite cmdlet creates a new site collection for the current tenant. Currently only 'modern' sites like Communication Site and the Modern Team Site are supported. If you want to create a classic site, use New-PnPTenantSite.", OutputType = typeof(string), OutputTypeDescription = "Returns the url of the newly created site collection", - DetailedDescription = @"The New-PnPSite cmdlet creates a new site collection for the current tenant. Currently only 'modern' sites like Communication Site and the Modern Team Site are supported. If you want to create a classic site, use New-PnPTenantSite.", Category = CmdletHelpCategory.TenantAdmin, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( Code = @"PS:> New-PnPSite -Type CommunicationSite -Title Contoso -Url https://tenant.sharepoint.com/sites/contoso", @@ -47,25 +47,25 @@ namespace SharePointPnP.PowerShell.Commands Code = @"PS:> New-PnPSite -Type TeamSite -Title Contoso -Alias contoso -IsPublic", Remarks = @"This will create a new Modern Team Site collection with the title 'Contoso' and the url 'https://tenant.sharepoint.com/sites/contoso' and sets the site to public.", SortOrder = 7)] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Title", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Title", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Title", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Url", Mandatory = true, HelpMessage = @"Specifies the full url of the new site collection", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Url", Mandatory = true, HelpMessage = @"Specifies the full url of the new site collection", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Url", Mandatory = true, HelpMessage = @"Specifies the full url of the new site collection", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Description", Mandatory = false, HelpMessage = @"Specifies the description of the new site collection", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Description", Mandatory = false, HelpMessage = @"Specifies the description of the new site collection", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Description", Mandatory = false, HelpMessage = @"Specifies the description of the new site collection", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Classification", Mandatory = false, HelpMessage = @"Specifies the classification of the new site collection", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Classification", Mandatory = false, HelpMessage = @"Specifies the classification of the new site collection", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Classification", Mandatory = false, HelpMessage = @"Specifies the classification of the new site collection", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(SwitchParameter), ParameterName = "AllowFileSharingForGuestUsers", Mandatory = false, HelpMessage = @"Specifies if guest users can share files in the new site collection", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(SwitchParameter), ParameterName = "AllowFileSharingForGuestUsers", Mandatory = false, HelpMessage = @"Specifies if guest users can share files in the new site collection", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(SwitchParameter), ParameterName = "AllowFileSharingForGuestUsers", Mandatory = false, HelpMessage = @"Specifies if guest users can share files in the new site collection", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(OfficeDevPnP.Core.Sites.CommunicationSiteDesign), ParameterName = "SiteDesign", Mandatory = false, HelpMessage = @"Specifies the site design of the new site collection. Defaults to 'Topic'", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(OfficeDevPnP.Core.Sites.CommunicationSiteDesign), ParameterName = "SiteDesign", Mandatory = false, HelpMessage = @"Specifies the site design of the new site collection. Defaults to 'Topic'", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(GuidPipeBind), ParameterName = "SiteDesignId", Mandatory = true, HelpMessage = @"Specifies the site design id to use for the new site collection. If specified will override SiteDesign", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(uint), ParameterName = "Lcid", Mandatory = false, HelpMessage = @"Specifies the language of the new site collection. Defaults to the current language of the web connected to.", ParameterSetName = "CommunicationBuiltInDesign")] + [CmdletAdditionalParameter(ParameterType = typeof(uint), ParameterName = "Lcid", Mandatory = false, HelpMessage = @"Specifies the language of the new site collection. Defaults to the current language of the web connected to.", ParameterSetName = "Communication Site With Built-in Design")] [CmdletAdditionalParameter(ParameterType = typeof(uint), ParameterName = "Lcid", Mandatory = false, HelpMessage = @"Specifies the language of the new site collection. Defaults to the current language of the web connected to.", ParameterSetName = "CommunicationCustomInDesign")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Title", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection", ParameterSetName = "TeamSite")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Alias", Mandatory = true, HelpMessage = @"Specifies the alias of the new site collection", ParameterSetName = "TeamSite")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Description", Mandatory = false, HelpMessage = @"Specifies the description of the new site collection", ParameterSetName = "TeamSite")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Classification", Mandatory = false, HelpMessage = @"Specifies the classification of the new site collection", ParameterSetName = "TeamSite")] - [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "IsPublic", Mandatory = false, HelpMessage = @"Specifies if new site collection is public. Defaults to false.", ParameterSetName = "TeamSite")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Title", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection", ParameterSetName = "Team Site")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Alias", Mandatory = true, HelpMessage = @"Specifies the alias of the new site collection", ParameterSetName = "Team Site")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Description", Mandatory = false, HelpMessage = @"Specifies the description of the new site collection", ParameterSetName = "Team Site")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "Classification", Mandatory = false, HelpMessage = @"Specifies the classification of the new site collection", ParameterSetName = "Team Site")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "IsPublic", Mandatory = false, HelpMessage = @"Specifies if new site collection is public. Defaults to false.", ParameterSetName = "Team Site")] public class NewSite : PnPCmdlet, IDynamicParameters { [Parameter(Mandatory = true, HelpMessage = "@Specifies with type of site to create.")] @@ -138,27 +138,27 @@ protected override void ExecuteCmdlet() public class CommunicationSiteParameters { - [Parameter(Mandatory = true, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = true, ParameterSetName = "Communication Site With Built-in Design")] [Parameter(Mandatory = true, ParameterSetName = "CommunicationCustomInDesign")] public string Title; - [Parameter(Mandatory = true, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = true, ParameterSetName = "Communication Site With Built-in Design")] [Parameter(Mandatory = true, ParameterSetName = "CommunicationCustomInDesign")] public string Url; - [Parameter(Mandatory = false, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = false, ParameterSetName = "Communication Site With Built-in Design")] [Parameter(Mandatory = false, ParameterSetName = "CommunicationCustomInDesign")] public string Description; - [Parameter(Mandatory = false, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = false, ParameterSetName = "Communication Site With Built-in Design")] [Parameter(Mandatory = false, ParameterSetName = "CommunicationCustomInDesign")] public string Classification; - [Parameter(Mandatory = false, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = false, ParameterSetName = "Communication Site With Built-in Design")] [Parameter(Mandatory = false, ParameterSetName = "CommunicationCustomInDesign")] public SwitchParameter AllowFileSharingForGuestUsers; - [Parameter(Mandatory = false, ParameterSetName = "CommunicationBuiltInDesign")] + [Parameter(Mandatory = false, ParameterSetName = "Communication Site With Built-in Design")] public OfficeDevPnP.Core.Sites.CommunicationSiteDesign SiteDesign = OfficeDevPnP.Core.Sites.CommunicationSiteDesign.Topic; [Parameter(Mandatory = true, ParameterSetName = "CommunicationCustomInDesign")] @@ -171,19 +171,19 @@ public class CommunicationSiteParameters public class TeamSiteParameters { - [Parameter(Mandatory = true, ParameterSetName = "TeamSite")] + [Parameter(Mandatory = true, ParameterSetName = "Team Site")] public string Title; - [Parameter(Mandatory = true, ParameterSetName = "TeamSite")] + [Parameter(Mandatory = true, ParameterSetName = "Team Site")] public string Alias; - [Parameter(Mandatory = false, ParameterSetName = "TeamSite")] + [Parameter(Mandatory = false, ParameterSetName = "Team Site")] public string Description; - [Parameter(Mandatory = false, ParameterSetName = "TeamSite")] + [Parameter(Mandatory = false, ParameterSetName = "Team Site")] public string Classification; - [Parameter(Mandatory = false, ParameterSetName = "TeamSite")] + [Parameter(Mandatory = false, ParameterSetName = "Team Site")] public SwitchParameter IsPublic; } } diff --git a/Commands/Admin/NewTenantSite.cs b/Commands/Admin/NewTenantSite.cs index 3ab3d735a..cff1d74d1 100644 --- a/Commands/Admin/NewTenantSite.cs +++ b/Commands/Admin/NewTenantSite.cs @@ -12,7 +12,7 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.New, "PnPTenantSite")] [CmdletHelp("Creates a new site collection for the current tenant", - DetailedDescription = @"The New-PnPTenantSite cmdlet creates a new site collection for the current company. However, creating a new SharePoint + @"The New-PnPTenantSite cmdlet creates a new site collection for the current company. However, creating a new SharePoint Online site collection fails if a deleted site with the same URL exists in the Recycle Bin. If you want to use this command for an on-premises farm, please refer to http://blogs.msdn.com/b/vesku/archive/2014/06/09/provisioning-site-collections-using-sp-app-model-in-on-premises-with-just-csom.aspx ", Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( diff --git a/Commands/Admin/RemoveTenantSite.cs b/Commands/Admin/RemoveTenantSite.cs index 1a3421bd7..2593d8dc9 100644 --- a/Commands/Admin/RemoveTenantSite.cs +++ b/Commands/Admin/RemoveTenantSite.cs @@ -10,7 +10,8 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Remove, "PnPTenantSite", ConfirmImpact = ConfirmImpact.High, SupportsShouldProcess = true)] - [CmdletHelp("Removes a site collection from the current tenant", + [CmdletHelp("Removes a site collection", + "Removes a site collection which is listed in your tenant administration site.", SupportedPlatform = CmdletSupportedPlatform.Online, Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( diff --git a/Commands/Admin/SetTenantSite.cs b/Commands/Admin/SetTenantSite.cs index 71a141c20..71758cc54 100644 --- a/Commands/Admin/SetTenantSite.cs +++ b/Commands/Admin/SetTenantSite.cs @@ -12,7 +12,8 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Set, "PnPTenantSite")] - [CmdletHelp(@"Uses the tenant API to set site information.", + [CmdletHelp(@"Set site information.", + "Sets site properties for existing sites.", SupportedPlatform = CmdletSupportedPlatform.Online, Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( diff --git a/Commands/Apps/AddApp.cs b/Commands/Apps/AddApp.cs new file mode 100644 index 000000000..7f0631fe9 --- /dev/null +++ b/Commands/Apps/AddApp.cs @@ -0,0 +1,37 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.ALM; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsCommon.Add, "PnPApp")] + [CmdletHelp("Add/uploads an available app to the app catalog", + Category = CmdletHelpCategory.Apps, SupportedPlatform = CmdletSupportedPlatform.Online, + OutputType = typeof(AppMetadata))] + [CmdletExample(Code = @"PS:> Add-PnPApp -Path ./myapp.sppkg", Remarks = @"This will upload the specified app package to the app catalog", SortOrder = 1)] + public class AddApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id or an actual app metadata instance")] + public string Path; + + protected override void ExecuteCmdlet() + { + if (!System.IO.Path.IsPathRooted(Path)) + { + Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); + } + + var fileInfo = new System.IO.FileInfo(Path); + + var bytes = System.IO.File.ReadAllBytes(Path); + + var manager = new AppManager(ClientContext); + + var result = manager.Add(bytes, fileInfo.Name); + + WriteObject(result); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Apps/GetApp.cs b/Commands/Apps/GetApp.cs new file mode 100644 index 000000000..43ebc9869 --- /dev/null +++ b/Commands/Apps/GetApp.cs @@ -0,0 +1,47 @@ +#if !ONPREMISES +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using OfficeDevPnP.Core.ALM; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsCommon.Get, "PnPApp")] + [CmdletHelp("Returns the available apps from the app catalog", + Category = CmdletHelpCategory.Apps, + OutputType = typeof(List), SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample(Code = @"PS:> Get-PnPAvailableApp", Remarks = @"This will return all available app metadata from the tenant app catalog. It will list the installed version in the current site.", SortOrder = 1)] + [CmdletExample(Code = @"PS:> Get-PnPAvailableApp -Identity 2646ccc3-6a2b-46ef-9273-81411cbbb60f", Remarks = @"This will the specific app metadata from the app catalog.", SortOrder = 2)] + public class GetApp : PnPCmdlet + { + [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id of an app which is available in the app catalog")] + public GuidPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var manager = new AppManager(ClientContext); + + var apps = manager.GetAvailable(); + if (MyInvocation.BoundParameters.ContainsKey("Identity")) + { + var app = apps.FirstOrDefault(a => a.Id == Identity.Id); + + if (app != null) + { + WriteObject(app); + } + else + { + throw new System.Exception("App not found"); + } + } + else + { + WriteObject(apps); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Apps/GetAppInstance.cs b/Commands/Apps/GetAppInstance.cs index 6ef1ba202..c96d3b211 100644 --- a/Commands/Apps/GetAppInstance.cs +++ b/Commands/Apps/GetAppInstance.cs @@ -8,7 +8,8 @@ namespace SharePointPnP.PowerShell.Commands.Apps { [Cmdlet(VerbsCommon.Get, "PnPAppInstance")] - [CmdletHelp("Returns a SharePoint AddIn Instance in the site", + [CmdletHelp("Returns a SharePoint AddIn Instance", + "Returns a SharePoint App/Addin that has been installed in the current site", Category = CmdletHelpCategory.Apps, OutputType = typeof(List), OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.appinstance.aspx")] diff --git a/Commands/Apps/ImportAppPackage.cs b/Commands/Apps/ImportAppPackage.cs index 15b4c2bdb..476c69edc 100644 --- a/Commands/Apps/ImportAppPackage.cs +++ b/Commands/Apps/ImportAppPackage.cs @@ -9,7 +9,7 @@ namespace SharePointPnP.PowerShell.Commands.Apps { [Cmdlet(VerbsData.Import, "PnPAppPackage")] [CmdletHelp("Adds a SharePoint Addin to a site", - DetailedDescription = "This commands requires that you have an addin package to deploy", + "This commands requires that you have an addin package to deploy", Category = CmdletHelpCategory.Apps, OutputType = typeof(AppInstance), OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.appinstance.aspx")] diff --git a/Commands/Apps/InstallApp.cs b/Commands/Apps/InstallApp.cs new file mode 100644 index 000000000..3f745eb1b --- /dev/null +++ b/Commands/Apps/InstallApp.cs @@ -0,0 +1,27 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.ALM; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsLifecycle.Install, "PnPApp")] + [CmdletHelp("Installs an available app from the app catalog", + Category = CmdletHelpCategory.Apps, SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample(Code = @"PS:> Install-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", Remarks = @"This will install an available app, specified by the id, to the current site.", SortOrder = 1)] + [CmdletExample(Code = @"PS:> Get-PnPAvailableApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe | Install-PnPApp", Remarks = @"This will install the given app into the site.", SortOrder = 2)] + public class InstallApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id or an actual app metadata instance")] + public AppMetadataPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var manager = new AppManager(ClientContext); + + manager.Install(Identity.GetId()); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Apps/PublishApp.cs b/Commands/Apps/PublishApp.cs new file mode 100644 index 000000000..f6ee7db8e --- /dev/null +++ b/Commands/Apps/PublishApp.cs @@ -0,0 +1,29 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsData.Publish, "PnPApp")] + [CmdletHelp("Publishes/Deploys/Trusts an available app in the app catalog", + Category = CmdletHelpCategory.Apps, SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample(Code = @"PS:> Publish-PnPApp", Remarks = @"This will deploy/trust an app into the app catalog. Notice that the app needs to be available in the app catalog", SortOrder = 1)] + + public class PublishApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id of the app")] + public AppMetadataPipeBind Identity; + + [Parameter(Mandatory = false)] + public SwitchParameter SkipFeatureDeployment; + + protected override void ExecuteCmdlet() + { + var manager = new OfficeDevPnP.Core.ALM.AppManager(ClientContext); + + manager.Deploy(Identity.GetId(),SkipFeatureDeployment); + } + } +} +#endif diff --git a/Commands/Apps/RemoveApp.cs b/Commands/Apps/RemoveApp.cs new file mode 100644 index 000000000..9ab2b5e47 --- /dev/null +++ b/Commands/Apps/RemoveApp.cs @@ -0,0 +1,25 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsCommon.Remove, "PnPApp")] + [CmdletHelp("Removes an app from the app catalog", SupportedPlatform = CmdletSupportedPlatform.Online, + Category = CmdletHelpCategory.Apps)] + [CmdletExample(Code = @"PS:> Remove-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", Remarks = @"This will remove the specified app from the app catalog", SortOrder = 1)] + public class RemoveApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id of the Addin Instance")] + public AppMetadataPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var manager = new OfficeDevPnP.Core.ALM.AppManager(ClientContext); + + manager.Remove(Identity.GetId()); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Apps/UninstallApp.cs b/Commands/Apps/UninstallApp.cs new file mode 100644 index 000000000..c0814a290 --- /dev/null +++ b/Commands/Apps/UninstallApp.cs @@ -0,0 +1,25 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsLifecycle.Uninstall, "PnPApp")] + [CmdletHelp("Uninstalls an available add-in from the site", + Category = CmdletHelpCategory.Apps)] + [CmdletExample(Code = @"PS:> Uninstall-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", Remarks = @"This will uninstall the specified app from the current site.", SortOrder = 2)] + public class UninstallApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id of the Addin Instance")] + public AppMetadataPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var manager = new OfficeDevPnP.Core.ALM.AppManager(ClientContext); + + manager.Uninstall(Identity.GetId()); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Apps/UninstallAppInstance.cs b/Commands/Apps/UninstallAppInstance.cs index f9bf33a5b..145a2ef17 100644 --- a/Commands/Apps/UninstallAppInstance.cs +++ b/Commands/Apps/UninstallAppInstance.cs @@ -6,7 +6,9 @@ namespace SharePointPnP.PowerShell.Commands.Apps { [Cmdlet(VerbsLifecycle.Uninstall, "PnPAppInstance", SupportsShouldProcess = true)] - [CmdletHelp("Removes an app from a site", Category = CmdletHelpCategory.Apps)] + [CmdletHelp("Removes an app from a site", + "Removes an add-in/app that has been installed to a site.", + Category = CmdletHelpCategory.Apps)] [CmdletExample(Code = @"PS:> Uninstall-PnPAppInstance -Identity $appinstance", Remarks = "Uninstalls the app instance which was retrieved with the command Get-PnPAppInstance", SortOrder = 1)] [CmdletExample(Code = @"PS:> Uninstall-PnPAppInstance -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", Remarks = "Uninstalls the app instance with the ID '99a00f6e-fb81-4dc7-8eac-e09c6f9132fe'", SortOrder = 2)] [CmdletExample(Code = @"PS:> Uninstall-PnPAppInstance -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe -force", Remarks = "Uninstalls the app instance with the ID '99a00f6e-fb81-4dc7-8eac-e09c6f9132fe' and do not ask for confirmation", SortOrder = 3)] @@ -23,10 +25,10 @@ protected override void ExecuteCmdlet() AppInstance instance; instance = Identity.GetAppInstance(SelectedWeb); - - if(instance != null) + + if (instance != null) { - if(!instance.IsObjectPropertyInstantiated("Title")) + if (!instance.IsObjectPropertyInstantiated("Title")) { ClientContext.Load(instance, i => i.Title); ClientContext.ExecuteQueryRetry(); diff --git a/Commands/Apps/UnpublishApp.cs b/Commands/Apps/UnpublishApp.cs new file mode 100644 index 000000000..313c3ee15 --- /dev/null +++ b/Commands/Apps/UnpublishApp.cs @@ -0,0 +1,25 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Apps +{ + [Cmdlet(VerbsData.Unpublish, "PnPApp")] + [CmdletHelp("Unpublishes/retracts an available add-in from the app catalog", + Category = CmdletHelpCategory.Apps, SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample(Code = @"PS:> Unpublish-PnPApp -Identity 99a00f6e-fb81-4dc7-8eac-e09c6f9132fe", Remarks = @"This will retract, but not remove, the specified app from the app catalog", SortOrder = 2)] + public class UnpublishApp : PnPCmdlet + { + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the Id of the Addin Instance")] + public AppMetadataPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var manager = new OfficeDevPnP.Core.ALM.AppManager(ClientContext); + + manager.Retract(Identity.GetId()); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index a4ae42471..45298b321 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -17,7 +17,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommunications.Connect, "PnPOnline", SupportsShouldProcess = false)] - [CmdletHelp("Connects to a SharePoint site and creates a context that is required for the other PnP Cmdlets", + [CmdletHelp("Connect to a SharePoint site", + "Connects to a SharePoint site and creates a context that is required for the other PnP Cmdlets", DetailedDescription = "If no credentials have been specified, and the CurrentCredentials parameter has not been specified, you will be prompted for credentials.", Category = CmdletHelpCategory.Base)] [CmdletExample( @@ -70,9 +71,9 @@ public class ConnectOnline : PSCmdlet private const string ParameterSet_TOKEN = "Token"; private const string ParameterSet_WEBLOGIN = "WebLogin"; #if !ONPREMISES - private const string ParameterSet_NATIVEAAD = "NativeAAD"; - private const string ParameterSet_APPONLYAAD = "AppOnlyAAD"; - private const string ParameterSet_SPOManagement = "SPOManagement"; + private const string ParameterSet_NATIVEAAD = "Azure Active Directory"; + private const string ParameterSet_APPONLYAAD = "App-Only with Azure Active Directory"; + private const string ParameterSet_SPOManagement = "SPO Management Shell Credentials"; private const string SPOManagementClientId = "9bc3ab49-b65d-410a-85ad-de819febfddc"; private const string SPOManagementRedirectUri = "https://oauth.spops.microsoft.com/"; #endif diff --git a/Commands/Base/ConnectPnPMicrosoftGraph.cs b/Commands/Base/ConnectPnPMicrosoftGraph.cs index 8772fba59..426c7707f 100644 --- a/Commands/Base/ConnectPnPMicrosoftGraph.cs +++ b/Commands/Base/ConnectPnPMicrosoftGraph.cs @@ -7,8 +7,9 @@ namespace SharePointPnP.PowerShell.Commands.Base { - [Cmdlet("Connect", "PnPMicrosoftGraph", DefaultParameterSetName = "Scope")] - [CmdletHelp("Uses the Microsoft Authentication Library (Preview) to connect to Azure AD and to get an OAuth 2.0 Access Token to consume the Microsoft Graph API", + [Cmdlet("Connect", "PnPMicrosoftGraph", DefaultParameterSetName = ParameterSet_SCOPE)] + [CmdletHelp("Connect to the Microsoft Graph", + "Uses the Microsoft Authentication Library (Preview) to connect to Azure AD and to get an OAuth 2.0 Access Token to consume the Microsoft Graph API", Category = CmdletHelpCategory.Graph)] [CmdletExample( Code = "PS:> Connect-PnPMicrosoftGraph -Scopes $arrayOfScopes", @@ -20,21 +21,23 @@ namespace SharePointPnP.PowerShell.Commands.Base SortOrder = 2)] public class ConnectPnPMicrosoftGraph : PSCmdlet { + private const string ParameterSet_SCOPE = "Scope"; + private const string ParameterSet_AAD = "AAD"; private const string MSALPnPPowerShellClientId = "bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71"; private const string RedirectUri = "urn:ietf:wg:oauth:2.0:oob"; private static readonly Uri AADLogin = new Uri("https://login.microsoftonline.com/"); private static readonly string[] DefaultScope = { "https://graph.microsoft.com/.default" }; - [Parameter(Mandatory = true, HelpMessage = "The array of permission scopes for the Microsoft Graph API.", ParameterSetName = "Scope")] + [Parameter(Mandatory = true, HelpMessage = "The array of permission scopes for the Microsoft Graph API.", ParameterSetName = ParameterSet_SCOPE)] public string[] Scopes; - [Parameter(Mandatory = true, HelpMessage = "The client id of the app which gives you access to the Microsoft Graph API.", ParameterSetName = "AAD")] + [Parameter(Mandatory = true, HelpMessage = "The client id of the app which gives you access to the Microsoft Graph API.", ParameterSetName = ParameterSet_AAD)] public string AppId; - [Parameter(Mandatory = true, HelpMessage = "The app key of the app which gives you access to the Microsoft Graph API.", ParameterSetName = "AAD")] + [Parameter(Mandatory = true, HelpMessage = "The app key of the app which gives you access to the Microsoft Graph API.", ParameterSetName = ParameterSet_AAD)] public string AppSecret; - [Parameter(Mandatory = true, HelpMessage = "The AAD where the O365 app is registred. Eg.: contoso.com, or contoso.onmicrosoft.com.", ParameterSetName = "AAD")] + [Parameter(Mandatory = true, HelpMessage = "The AAD where the O365 app is registred. Eg.: contoso.com, or contoso.onmicrosoft.com.", ParameterSetName = ParameterSet_AAD)] public string AADDomain; protected override void ProcessRecord() diff --git a/Commands/Base/DisconnectSPOnline.cs b/Commands/Base/DisconnectSPOnline.cs index 6379d1e79..98c3f2b7e 100644 --- a/Commands/Base/DisconnectSPOnline.cs +++ b/Commands/Base/DisconnectSPOnline.cs @@ -9,6 +9,7 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommunications.Disconnect, "PnPOnline")] [CmdletHelp("Disconnects the context", + "Disconnects the current context and requires you to build up a new connection in order to use the Cmdlets again. Using Connect-PnPOnline to connect to a different site has the same effect.", Category = CmdletHelpCategory.Base)] [CmdletExample( Code = @"PS:> Disconnect-PnPOnline", diff --git a/Commands/Base/ExecuteQuery.cs b/Commands/Base/ExecuteQuery.cs index 9447487c8..f17aaad5b 100644 --- a/Commands/Base/ExecuteQuery.cs +++ b/Commands/Base/ExecuteQuery.cs @@ -5,7 +5,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet("Execute", "PnPQuery")] - [CmdletHelp("Executes any queued actions / changes on the SharePoint Client Side Object Model Context", + [CmdletHelp("Execute the current queued actions", + "Executes any queued actions / changes on the SharePoint Client Side Object Model Context", Category = CmdletHelpCategory.Base)] [CmdletExample( Code = @"PS:> Execute-PnPQuery -RetryCount 5", @@ -24,7 +25,7 @@ public class ExecuteSPOQuery : PnPCmdlet protected override void ProcessRecord() { - ClientContext.ExecuteQueryRetry(RetryCount,RetryWait); + ClientContext.ExecuteQueryRetry(RetryCount, RetryWait); } } } diff --git a/Commands/Base/GetAppAuthAccessToken.cs b/Commands/Base/GetAppAuthAccessToken.cs index d9bccf3bc..847d931f0 100644 --- a/Commands/Base/GetAppAuthAccessToken.cs +++ b/Commands/Base/GetAppAuthAccessToken.cs @@ -7,14 +7,15 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Get, "PnPAppAuthAccessToken")] - [CmdletHelp("Returns the access token from the current client context (In App authentication mode only)", + [CmdletHelp("Returns the access token", + "Returns the access token from the current client context (only works with App-Only authentication)", Category = CmdletHelpCategory.Base, OutputType = typeof(string), OutputTypeLink = "https://msdn.microsoft.com/en-us/library/system.string.aspx")] [CmdletExample( Code = @"PS:> $accessToken = Get-PnPAppAuthAccessToken", Remarks = @"This will put the access token from current context in the $accessToken variable. Will only work in App authentication flow (App+user or App-Only)", - SortOrder = 1)] + SortOrder = 1)] public class GetPnPAppAuthAccessToken : PnPCmdlet { protected override void ExecuteCmdlet() diff --git a/Commands/Base/GetAuthenticationRealm.cs b/Commands/Base/GetAuthenticationRealm.cs index 8981d32dc..4b24104ce 100644 --- a/Commands/Base/GetAuthenticationRealm.cs +++ b/Commands/Base/GetAuthenticationRealm.cs @@ -7,10 +7,12 @@ namespace SharePointPnP.PowerShell.Commands { [Cmdlet(VerbsCommon.Get, "PnPAuthenticationRealm")] - [CmdletHelp("Gets the authentication realm for the current web", + [CmdletHelp("Returns the authentication realm", + "Gets the authentication realm for the current web", + OutputType = typeof(string), Category = CmdletHelpCategory.Base)] [CmdletExample( - Code = @"PS:> Get-PnPAuthenticationRealm", + Code = @"PS:> Get-PnPAuthenticationRealm", Remarks = @"This will get the authentication realm for the current connected site", SortOrder = 1)] [CmdletExample( @@ -20,12 +22,12 @@ namespace SharePointPnP.PowerShell.Commands public class GetAuthenticationRealm : PnPCmdlet { - [Parameter(Mandatory = false, Position=0, ValueFromPipeline=true, HelpMessage = "Specifies the URL of the site")] + [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, HelpMessage = "Specifies the URL of the site")] public string Url; protected override void ProcessRecord() { - if(string.IsNullOrEmpty(Url)) + if (string.IsNullOrEmpty(Url)) { Url = ClientContext.Url; } diff --git a/Commands/Base/GetAzureADManifestKeyCredentials.cs b/Commands/Base/GetAzureADManifestKeyCredentials.cs index 3bee23f04..f87912265 100644 --- a/Commands/Base/GetAzureADManifestKeyCredentials.cs +++ b/Commands/Base/GetAzureADManifestKeyCredentials.cs @@ -6,7 +6,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Get, "PnPAzureADManifestKeyCredentials")] - [CmdletHelp("Creates the JSON snippet that is required for the manifest JSON file for Azure WebApplication / WebAPI apps", + [CmdletHelp("Return the JSON Manifest snippet for Azure Apps", + "Creates the JSON snippet that is required for the manifest JSON file for Azure WebApplication / WebAPI apps", Category = CmdletHelpCategory.Base, OutputType=typeof(string), OutputTypeDescription = "Outputs a JSON formatted string")] diff --git a/Commands/Base/GetContext.cs b/Commands/Base/GetContext.cs index 9a5093f8a..4058075c8 100644 --- a/Commands/Base/GetContext.cs +++ b/Commands/Base/GetContext.cs @@ -6,14 +6,15 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Get, "PnPContext")] - [CmdletHelp("Returns a Client Side Object Model context", + [CmdletHelp("Returns the current context", + "Returns a Client Side Object Model context", Category = CmdletHelpCategory.Base, OutputType = typeof(Microsoft.SharePoint.Client.ClientContext), OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.clientcontext.aspx")] [CmdletExample( Code = @"PS:> $ctx = Get-PnPContext", Remarks = @"This will put the current context in the $ctx variable.", - SortOrder = 1)] + SortOrder = 1)] public class GetSPOContext : PSCmdlet { diff --git a/Commands/Base/GetHealthScore.cs b/Commands/Base/GetHealthScore.cs index d36753171..3feb68835 100644 --- a/Commands/Base/GetHealthScore.cs +++ b/Commands/Base/GetHealthScore.cs @@ -6,7 +6,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet("Get", "PnPHealthScore")] - [CmdletHelp("Retrieves the current health score value of the server", + [CmdletHelp("Retrieves the healthscore", + "Retrieves the current health score value of the server which is a value between 0 and 10. Lower is better.", Category = CmdletHelpCategory.Base, OutputType=typeof(int), OutputTypeDescription = "Returns a int value representing the current health score value of the server.")] diff --git a/Commands/Base/GetPnPAccessToken.cs b/Commands/Base/GetPnPAccessToken.cs index 4bde3a644..41cf72221 100644 --- a/Commands/Base/GetPnPAccessToken.cs +++ b/Commands/Base/GetPnPAccessToken.cs @@ -9,7 +9,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet("Get", "PnPAccessToken")] - [CmdletHelp("Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API", + [CmdletHelp("Returns the current OAuth Access token", + "Gets the OAuth 2.0 Access Token to consume the Microsoft Graph API", Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( Code = "PS:> Get-PnPAccessToken", diff --git a/Commands/Base/GetProperty.cs b/Commands/Base/GetProperty.cs index bc7295325..289c84dee 100644 --- a/Commands/Base/GetProperty.cs +++ b/Commands/Base/GetProperty.cs @@ -7,7 +7,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Get, "PnPProperty")] - [CmdletHelp("Will populate properties of an object and optionally, if needed, load the value from the server. If one property is specified its value will be returned to the output.", + [CmdletHelp("Returns a previously not loaded property of a ClientObject", + "Will populate properties of an object and optionally, if needed, load the value from the server. If one property is specified its value will be returned to the output.", Category = CmdletHelpCategory.Base, OutputType = typeof(ClientObject), OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.clientobject.aspx")] diff --git a/Commands/Base/GetStoredCredential.cs b/Commands/Base/GetStoredCredential.cs index aa8f8db47..78a482730 100644 --- a/Commands/Base/GetStoredCredential.cs +++ b/Commands/Base/GetStoredCredential.cs @@ -6,12 +6,13 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet("Get", "PnPStoredCredential")] - [CmdletHelp("Returns a stored credential from the Windows Credential Manager", + [CmdletHelp("Get a credential", + "Returns a stored credential from the Windows Credential Manager", Category = CmdletHelpCategory.Base)] - [CmdletExample(Code = "PS:> Get-PnPStoredCredential -Name O365", + [CmdletExample(Code = "PS:> Get-PnPStoredCredential -Name O365", Remarks = "Returns the credential associated with the specified identifier", SortOrder = 1)] - [CmdletExample(Code = "PS:> Get-PnPStoredCredential -Name testEnvironment -Type OnPrem", + [CmdletExample(Code = "PS:> Get-PnPStoredCredential -Name testEnvironment -Type OnPrem", Remarks = "Gets the credential associated with the specified identifier from the credential manager and then will return a credential that can be used for on-premises authentication", SortOrder = 2)] public class GetStoredCredential : PSCmdlet diff --git a/Commands/Base/PipeBinds/AppMetadataPipeBind.cs b/Commands/Base/PipeBinds/AppMetadataPipeBind.cs new file mode 100644 index 000000000..482107540 --- /dev/null +++ b/Commands/Base/PipeBinds/AppMetadataPipeBind.cs @@ -0,0 +1,43 @@ +#if !ONPREMISES +using Microsoft.SharePoint.Client; +using OfficeDevPnP.Core.ALM; +using System; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class AppMetadataPipeBind + { + private readonly AppMetadata _appMetadata; + private readonly Guid _id; + + public AppMetadataPipeBind(AppMetadata metadata) + { + _appMetadata = metadata; + } + + + public AppMetadataPipeBind(Guid guid) + { + _id = guid; + } + + public AppMetadataPipeBind(string id) + { + _id = Guid.Parse(id); + } + + public Guid GetId() + { + if (_appMetadata != null) + { + return _appMetadata.Id; + } + else + { + return _id; + } + } + } + +} +#endif \ No newline at end of file diff --git a/Commands/Base/SetContext.cs b/Commands/Base/SetContext.cs index 8ee12fa08..4e0e6c7e5 100644 --- a/Commands/Base/SetContext.cs +++ b/Commands/Base/SetContext.cs @@ -5,7 +5,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Set, "PnPContext")] - [CmdletHelp("Sets the Client Context to use by the cmdlets", + [CmdletHelp("Set the ClientContext", + "Sets the Client Context to use by the cmdlets, which allows easy context switching. See examples for details.", Category = CmdletHelpCategory.Base)] [CmdletExample( Code = @"PS:> Connect-PnPOnline -Url $siteAurl -Credentials $credentials diff --git a/Commands/Base/SetTraceLog.cs b/Commands/Base/SetTraceLog.cs index 0845edd3d..698f6aa15 100644 --- a/Commands/Base/SetTraceLog.cs +++ b/Commands/Base/SetTraceLog.cs @@ -6,7 +6,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommon.Set, "PnPTraceLog")] - [CmdletHelp("Defines if tracing should be turned on. PnP Core, which is the foundation of these cmdlets uses the standard Trace functionality of .NET. With this cmdlet you can turn capturing of this trace to a log file on or off.", + [CmdletHelp("Turn log tracing on or off", + "Defines if tracing should be turned on. PnP Core, which is the foundation of these cmdlets, uses the standard Trace functionality of .NET. With this cmdlet you can turn capturing of this trace to a log file on or off.", Category = CmdletHelpCategory.Base)] [CmdletExample( Code = @"PS:> Set-PnPTraceLog -On -LogFile traceoutput.txt", diff --git a/Commands/Branding/AddCustomAction.cs b/Commands/Branding/AddCustomAction.cs index c420e0226..24fcde915 100644 --- a/Commands/Branding/AddCustomAction.cs +++ b/Commands/Branding/AddCustomAction.cs @@ -10,7 +10,9 @@ namespace SharePointPnP.PowerShell.Commands.Branding { [Cmdlet(VerbsCommon.Add, "PnPCustomAction")] - [CmdletHelp("Adds a custom action to a web", Category = CmdletHelpCategory.Branding)] + [CmdletHelp("Adds a custom action", + "Adds a user custom action to a web or sitecollection.", + Category = CmdletHelpCategory.Branding)] [CmdletExample(Code = @"$cUIExtn = ""