XWikiAutomation.psm1
# Copyright WebMD Health Services # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License #Requires -Version 5.1 Set-StrictMode -Version 'Latest' # Functions should use $moduleRoot as the relative root from which to find # things. A published module has its function appended to this file, while a # module in development has its functions in the Functions directory. $moduleRoot = $PSScriptRoot # Store each of your module's functions in its own file in the Functions # directory. On the build server, your module's functions will be appended to # this file, so only dot-source files that exist on the file system. This allows # developers to work on a module without having to build it first. Grab all the # functions that are in their own files. $functionsPath = Join-Path -Path $moduleRoot -ChildPath 'Functions\*.ps1' if( (Test-Path -Path $functionsPath) ) { foreach( $functionPath in (Get-Item $functionsPath) ) { . $functionPath.FullName } } function Get-XWPage { <# .SYNOPSIS Gets all pages inside of a space. .DESCRIPTION The `Get-XWPage` function gets all of the content for all of the pages in a given space. Provide the path to the space as the `SpacePath` parameter. To get the details on a specific page rather than all pages inside of a space, provide the name of the page to the `Name` parameter. .EXAMPLE Get-XWPage -Session $session -SpacePath 'foo', 'bar' Demonstrates getting all of the pages within the space 'foo/bar'. .EXAMPLE Get-XWPage -Session $session -SpacePath 'Main' -Name 'MyPage' Demonstrates getting the page named 'MyPage'inside of the space named 'Main'. .EXAMPLE Get-XWPage -Session $session -SpacePath 'scooby', 'doo' -WikiName 'cartoons' Demonstrates getting all of the pages within the space 'scooby/doo' inside of the wiki named 'cartoons'. #> [CmdletBinding()] param( # The Session object for an XWiki session. Create a new Session using `New-XWSession`. [Parameter(Mandatory)] [Object] $Session, # The space path to get to the page. [Parameter(Mandatory)] [String[]] $SpacePath, # The name of the page. [String] $Name, # The name of the wiki the page belongs to. Defaults to xwiki. [String] $WikiName = 'xwiki' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $path = "wikis/${WikiName}/spaces/$($SpacePath -join '/spaces/')/pages" Write-Debug $path if ($Name) { $path = "${path}/${Name}" } $res = Invoke-XWRestMethod -Session $Session -Name $path -AsJson if (-not $Name) { $res = $res | Select-Object -ExpandProperty 'pageSummaries' } return $res | Select-Object -ExcludeProperty 'links' } function Get-XWWikis { <# .SYNOPSIS Lists the wikis on an XWiki instance. .DESCRIPTION The `Get-XWikis` function gets all of the parent wikis within an XWiki instance. On most XWikis, this should just return an XWiki named `xwiki`. .EXAMPLE Get-XWWikis -Session $Session Demonstrates listing all of the wikis on an XWiki instance. #> [CmdletBinding()] param( # The Session object for an XWiki session. Create a new Session using `New-XWSession`. [Parameter(Mandatory)] [pscustomobject] $Session ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState Invoke-XWRestMethod -Session $Session -Name 'wikis' -AsJson | Select-Object -ExpandProperty 'wikis' | Write-Output } function Invoke-XWRestMethod { <# .SYNOPSIS Invokes an XWiki Rest endpoint. .DESCRIPTION The `Invoke-XWRestMethod` invokes a XWiki REST API method. You pass the path to the endpoint (everything after `/xwiki/rest`) via the `Name` parameter, the HTTP method to use via the `Method` parameter, and the parameters to pass in the body of the request via the `Parameter` parameter. XWiki allows for returning REST API requests in both JSON and XML formats. The default return format is XML, to change this to JSON use the `AsJson` switch. When trying to update or create data on the XWiki server, it is recommended to use PUT requests rather than POST requests. This is due to the way XWiki handles requests. When using the `WhatIf` parameter, only web requests that use the `Get` HTTP method are made. .EXAMPLE Invoke-XWRestMethod -Session $session -Name 'wikis' Demonstrates using the `xwiki/rest/wikis` endpoint with a GET request to find a list of all of the wikis available. .LINK https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/Features/XWikiRESTfulAPI #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName='NoBody')] param( # The Session object for an XWiki session. Create a new Session using `New-XWSession`. [Parameter(Mandatory)] [pscustomobject] $Session, # The name of the API endpoint to make a request to. This should be everything after the `/xwiki/rest/` in the URL. [Parameter(Mandatory)] [String] $Name, # The REST method to use when making a request. Defaults to GET. [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = [Microsoft.PowerShell.Commands.WebRequestMethod]::Get, # Sets the content to be returned as JSON rather than returned as XML. [switch] $AsJson, # The body of the request. This is used for POST and PUT requests. [Parameter(Mandatory, ParameterSetName='Body')] [Object] $Body, # The content type of the body. Defaults to `application/xml`. [Parameter(ParameterSetName='Body')] [String] $ContentType = 'application/xml', # The form data to send with the request. This is used for POST and PUT requests. [Parameter(ParameterSetName='Form')] [hashtable] $Form ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $url = [uri]::EscapeUriString("$($Session.Url)rest/${name}") if ($AsJson) { $url = "${url}?media=json" } $requestParams = @{} if ($Body) { $requestParams['Body'] = $Body $requestParams['ContentType'] = $ContentType } if ($Form) { $requestParams['Body'] = $Form $requestParams['ContentType'] = 'application/x-www-form-urlencoded' } Write-Debug "${method} - ${url}" foreach ($key in $requestParams.Keys) { if ($key -ne 'Form') { Write-Debug "${key}: $($requestParams[$key])" } else { foreach ($formKey in $requestParams[$key].Keys) { Write-Debug " ${formKey}: $($requestParams[$key][$formKey])" } } } $auth = "$($Session.Credential.UserName):$($Session.Credential.GetNetworkCredential().Password)" $bytes = [Text.Encoding]::ASCII.GetBytes($auth) $base64AuthInfo = [Convert]::ToBase64String($bytes) $headers = @{ Authorization="Basic $base64AuthInfo" } if ($Session.Url.ToString().Contains('xwikiplayground')) { } try { if ($Method -eq [Microsoft.PowerShell.Commands.WebRequestMethod]::Get -or $PSCmdlet.ShouldProcess($url, $method)) { Invoke-RestMethod -Headers $headers -Method $Method -Uri $url @requestParams -UseBasicParsing | ForEach-Object { $_ } | Where-Object { $_ } | Write-Output } } catch { $Global:Error.RemoveAt(0) } } function New-XWSession { <# .SYNOPSIS Creates a session object used to communicate with an XWiki instance. .DESCRIPTION The `New-BMSession` function creates and returns a session object that is required by any function in the XWikiAutomation module that communicates with XWiki. The session includes XWiki's URL and the credentials to use when making requests to XWiki's APIs. .EXAMPLE $session = New-XWSession -Url 'https://xwiki.com' -Credential $credential Demonstrates how to call `New-XWSession`. In this case, the returned session object can be passed to other BuildMasterAutomation module functions to communicate with XWiki at `https://xwiki.com` with the credential in `$credential`. #> [CmdletBinding()] param( # The URL to the XWiki instance to use. [Parameter(Mandatory)] [Uri] $Url, # The username and password to use when making requests to XWiki. [Parameter(Mandatory)] [pscredential] $Credential ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState if (-not $Url.AbsolutePath.EndsWith('/')) { $Url = [uri]::new($Url, '/') } return [pscustomobject]@{ Url = $Url; Credential = $Credential; } } function Remove-XWPage { <# .SYNOPSIS Deletes an XWiki page. .DESCRIPTION The `Remove-XWPage` function deletes an XWiki page. Provide the path to the space and the name of the page to delete. If the page does not exist, no action is taken. .EXAMPLE Remove-XWPage -Session $session -SpacePath 'Main' -Name 'HomePage' Demonstrates deleting the page named 'HomePage' in the space 'Main'. .EXAMPLE Remove-XWPage -Session $session -SpacePath 'Main' -Name 'Snoopy' -WikiName 'cartoons' Demonstrates deleting the page named 'Snoopy' in the space 'Main' in the wiki named 'cartoons'. #> [Diagnostics.CodeAnalysis.SuppressMessage('PSShouldProcess', '')] [CmdletBinding(SupportsShouldProcess)] param( # The Session object for an XWiki session. Create a new Session using `New-XWSession`. [Parameter(Mandatory)] [Object] $Session, # The space path to get to the page. [Parameter(Mandatory)] [String[]] $SpacePath, # The name of the page. [Parameter(Mandatory)] [String] $Name, # The name of the wiki the page belongs to. Defaults to xwiki. [String] $WikiName = 'xwiki' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $path = "wikis/${WikiName}/spaces/$($SpacePath -join '/spaces/')/pages/${Name}" Invoke-XWRestMethod -Session $Session -Name $path -Method Delete } function Set-XWPage { <# .SYNOPSIS Creates or edits an XWiki page. .DESCRIPTION The `Set-XWPage` function creates or edits an XWiki page. It can set the title, parent page, hidden status, and the content of the page. If the page already exists, it will be updated with the new information. Only the fields that are edited need to be provided. .EXAMPLE Set-XWPage -Session $session -SpacePath 'Main' -Name 'HomePage' -Title 'XWiki Home' Demonstrates creating or editing a page named 'HomePage' in the space 'Main' with the title 'XWiki Home'. .EXAMPLE Set-XWPage -Session $session -SpacePath 'Main' -Name 'HomePage' -Content 'This is the content of the page.' Demonstrates creating or editing a page named 'HomePage' in the space 'Main' with the content 'This is the content of the page.' .EXAMPLE Set-XWPage -Session $session -SpacePath 'Main' -Name 'HomePage' -Hidden $true Demonstrates creating or editing a page named 'HomePage' in the space 'Main' and hiding it. .EXAMPLE Set-XWPage -Session $session -SpacePath 'Main' -Name 'HomePage' -Parent 'ParentPage' Demonstrates creating or editing a page named 'HomePage' in the space 'Main' with the parent page 'ParentPage'. If the page already exists, it will be moved to be a child of 'ParentPage'. #> [Diagnostics.CodeAnalysis.SuppressMessage('PSShouldProcess', '')] [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName='ByAttribute')] param ( # The Session object for an XWiki session. Create a new Session using `New-XWSession`. [Parameter(Mandatory)] [Object] $Session, # The space path to get to the page. [Parameter(Mandatory)] [String[]] $SpacePath, # The name of the page to edit. [Parameter(Mandatory)] [String] $Name, # The new title of the page. [Parameter(ParameterSetName='ByAttribute')] [String] $Title, # The new parent page of this page. [Parameter(ParameterSetName='ByAttribute')] [String] $Parent, # Whether the page should be hidden or not. [Parameter(ParameterSetName='ByAttribute')] [bool] $Hidden, # The new content of the page. [Parameter(ParameterSetName='ByAttribute')] [String] $Content, # An XML object representing the page. [Parameter(ParameterSetName='ByXML')] [xml] $Body, # The name of the wiki the page belongs to. Defaults to xwiki. [String] $WikiName = 'xwiki' ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $path = "wikis/${WikiName}/spaces/$($SpacePath -join '/spaces/')/pages/${Name}" if ($PSCmdlet.ParameterSetName -eq 'ByXML') { return Invoke-XWRestMethod -Session $Session -Name $path -Method Put -Body $body.ToString() } $formData = @{} if ($Title) { $formData['title'] = $Title } if ($Parent) { $formData['parent'] = $Parent } if ($null -ne $Hidden) { $formData['hidden'] = $Hidden } if ($Content) { $formData['content'] = $Content } Invoke-XWRestMethod -Session $session -Name $path -Method Put -Form $formData | Select-Object -ExpandProperty 'page' } function Use-CallerPreference { <# .SYNOPSIS Sets the PowerShell preference variables in a module's function based on the callers preferences. .DESCRIPTION Script module functions do not automatically inherit their caller's variables, including preferences set by common parameters. This means if you call a script with switches like `-Verbose` or `-WhatIf`, those that parameter don't get passed into any function that belongs to a module. When used in a module function, `Use-CallerPreference` will grab the value of these common parameters used by the function's caller: * ErrorAction * Debug * Confirm * InformationAction * Verbose * WarningAction * WhatIf This function should be used in a module's function to grab the caller's preference variables so the caller doesn't have to explicitly pass common parameters to the module function. This function is adapted from the [`Get-CallerPreference` function written by David Wyatt](https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d). There is currently a [bug in PowerShell](https://connect.microsoft.com/PowerShell/Feedback/Details/763621) that causes an error when `ErrorAction` is implicitly set to `Ignore`. If you use this function, you'll need to add explicit `-ErrorAction $ErrorActionPreference` to every `Write-Error` call. Please vote up this issue so it can get fixed. .LINK about_Preference_Variables .LINK about_CommonParameters .LINK https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d .LINK http://powershell.org/wp/2014/01/13/getting-your-script-module-functions-to-inherit-preference-variables-from-the-caller/ .EXAMPLE Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState Demonstrates how to set the caller's common parameter preference variables in a module function. #> [CmdletBinding()] param ( [Parameter(Mandatory)] #[Management.Automation.PSScriptCmdlet] # The module function's `$PSCmdlet` object. Requires the function be decorated with the `[CmdletBinding()]` # attribute. $Cmdlet, [Parameter(Mandatory)] # The module function's `$ExecutionContext.SessionState` object. Requires the function be decorated with the # `[CmdletBinding()]` attribute. # # Used to set variables in its callers' scope, even if that caller is in a different script module. [Management.Automation.SessionState]$SessionState ) Set-StrictMode -Version 'Latest' # List of preference variables taken from the about_Preference_Variables and their common parameter name (taken # from about_CommonParameters). $commonPreferences = @{ 'ErrorActionPreference' = 'ErrorAction'; 'DebugPreference' = 'Debug'; 'ConfirmPreference' = 'Confirm'; 'InformationPreference' = 'InformationAction'; 'VerbosePreference' = 'Verbose'; 'WarningPreference' = 'WarningAction'; 'WhatIfPreference' = 'WhatIf'; } foreach( $prefName in $commonPreferences.Keys ) { $parameterName = $commonPreferences[$prefName] # Don't do anything if the parameter was passed in. if( $Cmdlet.MyInvocation.BoundParameters.ContainsKey($parameterName) ) { continue } $variable = $Cmdlet.SessionState.PSVariable.Get($prefName) # Don't do anything if caller didn't use a common parameter. if( -not $variable ) { continue } if( $SessionState -eq $ExecutionContext.SessionState ) { Set-Variable -Scope 1 -Name $variable.Name -Value $variable.Value -Force -Confirm:$false -WhatIf:$false } else { $SessionState.PSVariable.Set($variable.Name, $variable.Value) } } } |