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 ConvertTo-XWSpacePath { <# .SYNOPSIS Converts a page reference to a space path. .DESCRIPTION The `ConvertTo-XWSpacePath` function converts a page reference to a space path. The page reference is a string that is provided by XWiki to identify a page. The page reference is in the format `space.page`. This function will split the page reference on the `.` character unless it is escaped with a `\`. It is returned as a hashtable with the spacepath under the key `SpacePath`, and the page name under the key `PageName`. .EXAMPLE ConvertTo-XWSpacePath -PageReference 'Main.WebHome' Demonstrates converting the page reference 'Main.WebHome' to the space path 'Main', 'WebHome'. #> [CmdletBinding()] param( # The page reference to convert. [Parameter(Mandatory)] [String] $PageReference ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $parts = $PageReference -split '(?<!\\)\.' $pageName = $parts[$parts.Length - 1] $spacePath = $parts[0..($parts.Length - 2)] return @{ SpacePath = $spacePath PageName = $pageName } } function Get-XWAttachment { <# .SYNOPSIS Get an attachment from a page. .DESCRIPTION The `Get-XWAttachment` function gets an attachment from a page. If provided with an `AttachmentName`, it will download the attachment with that name. If not, it will get the metadata for all attachments. If the attachment is an image or another type of file that cannot be displayed as text, you can use the `OutFile` parameter to save the attachment to a file. .EXAMPLE Get-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' Demonstrates getting metadata for all attachments on the page 'WebHome' in the 'Sandbox' space. .EXAMPLE Get-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' -AttachmentName 'LICENSE.txt' Demonstrates getting the contents of the attachment named 'LICENSE.txt' on the page 'WebHome' in the 'Sandbox' space. This will return the contents of the attachment as a string. .EXAMPLE Get-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' -AttachmentName 'XWikiLogo.png' -OutFile 'C:\temp\XWikiLogo.png' Demonstrates saving the attachment named 'XWikiLogo.png' on the page 'WebHome' in the 'Sandbox' space to the file at the path 'C:\temp\XWikiLogo.png'. #> [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. [Parameter(Mandatory)] [String] $PageName, # The name of the wiki the page belongs to. Defaults to xwiki. [String] $WikiName = 'xwiki', # The name of the attachment to get. [String] $AttachmentName, # The path to save the attachment to. [String] $OutFile ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState $path = "wikis/$WikiName/spaces/$($SpacePath -join '/')/pages/$PageName/attachments" $params = @{} if ($OutFile) { $params['OutFile'] = $OutFile } if ($AttachmentName) { $path += "/$AttachmentName" return Invoke-XWRestMethod -Session $Session -Name $path @params } Invoke-XWRestMethod -Session $Session -Name $path -AsJson @params | Select-Object -ExpandProperty 'attachments' } 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-XWWiki { <# .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. To upload a file to the XWiki server, use the `Invoke-XWRestMethod` function with the `InFile` parameter. This will send the file as the body of the request. To download a file from the XWiki server, use the `Invoke-XWRestMethod` function with the `OutFile` parameter. This will save the file to the path specified in the `OutFile` parameter. 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, [String] $OutFile, [String] $InFile ) 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 ($OutFile) { $requestParams['OutFile'] = $OutFile } if ($InFile) { $requestParams['InFile'] = $InFile } 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-XWAttachment { <# .SYNOPSIS Uploads an attachment to a page. .DESCRIPTION The `Set-XWAttachment` function uploads an attachment to a page. Provide the path to the space as the `SpacePath` parameter, the name of the page as the `PageName` parameter, and the name of the attachment as the `AttachmentName`. You can provide the content of the attachment as a string via the `Content` parameter or as a file via the `InFile` parameter. .EXAMPLE Set-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' -AttachmentName 'MyTextFile.txt' -Content 'Hello, World!' Demonstrates uploading a text file named 'MyTextFile.txt' with the content 'Hello, World!' to the page 'WebHome' in the 'Sandbox' space. .EXAMPLE Set-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' -AttachmentName 'MyTextFile.txt' -InFile 'C:\temp\MyTextFile.txt' Demonstrates uploading a text file named 'MyTextFile.txt' with the content of the file at 'C:\temp\MyTextFile.txt' to the page 'WebHome' in the 'Sandbox' space. .EXAMPLE Set-XWAttachment -Session $session -SpacePath 'Sandbox' -PageName 'WebHome' -AttachmentName 'XWikiLogo.png' -InFile 'C:\temp\XWikiLogo.png' Demonstrates uploading an image file named 'XWikiLogo.png' with the content of the file at 'C:\temp\XWikiLogo.png' to the page 'WebHome' in the 'Sandbox' space. #> [Diagnostics.CodeAnalysis.SuppressMessage('PSShouldProcess', '')] [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName='InFile')] 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] $PageName, # The name of the attachment. [Parameter(Mandatory)] [String] $AttachmentName, # The path to the file to upload. [Parameter(Mandatory, ParameterSetName='InFile')] [String] $InFile, # The content of the attachment. [Parameter(Mandatory, ParameterSetName='Content')] [String] $Content, # 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 '/')/pages/$PageName/attachments/$AttachmentName" if ($PSCmdlet.ParameterSetName -eq 'InFile') { return Invoke-XWRestMethod -Session $Session -Name $path -Method Put -InFile $InFile } return Invoke-XWRestMethod -Session $Session -Name $path -Method Put -Body $Content } 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) } } } |