├── .GITIGNORE
├── docs
├── .nojekyll
├── use
│ ├── use_loadadmin.md
│ ├── use_systeminfo.md
│ ├── use_tasks.md
│ ├── use_connect.md
│ ├── use_icons.md
│ ├── use_directoryjunction.md
│ ├── use_appassignments.md
│ ├── use_platlayers.md
│ ├── use_applayers.md
│ ├── use_oslayers.md
│ ├── use_exportimportlayers.md
│ ├── use_connectors.md
│ └── use_images.md
├── install.md
├── Makefile
├── index.rst
├── make.bat
├── changelog.rst
└── cmd
│ ├── cmd_disconnect.rst
│ ├── cmd_connect.rst
│ ├── cmd_stop.rst
│ └── cmd_export.rst
├── Examples
├── README.MD
├── GetUserAppAssignments.ps1
└── UpdateTask.ps1
├── .github
└── FUNDING.yml
├── Tests
├── ctxal-sdk.tests.ps1
└── Main.tests.ps1
├── ctxal-sdk
├── ctxal-sdk.psm1
├── Public
│ ├── Get-ALVMName.ps1
│ ├── disconnect-alsession.ps1
│ ├── Get-ALconnectoragent.ps1
│ ├── get-alCachePointInfo.ps1
│ ├── get-alicon.ps1
│ ├── get-aliconassoc.ps1
│ ├── stop-alworkticket.ps1
│ ├── Get-AlLocalUser.ps1
│ ├── remove-alicon.ps1
│ ├── get-alimage.ps1
│ ├── get-aloslayer.ps1
│ ├── get-alSystemsettingInfo.ps1
│ ├── get-alDirectoryDetail.ps1
│ ├── get-alremoteshare.ps1
│ ├── get-alplatformlayer.ps1
│ ├── get-alapplayer.ps1
│ ├── Get-ALPendingOp.ps1
│ ├── get-alimageDetail.ps1
│ ├── get-alconnectortype.ps1
│ ├── get-aloslayerdetail.ps1
│ ├── get-alSysteminfo.ps1
│ ├── get-allayerinstalldisk.ps1
│ ├── get-alstatus.ps1
│ ├── get-alplatformlayerDetail.ps1
│ ├── get-alapplayerdetail.ps1
│ ├── remove-alconnector.ps1
│ ├── Remove-ALImage.ps1
│ ├── New-ALImageClone.ps1
│ ├── remove-aldirectory.ps1
│ ├── invoke-alCreateBundle.ps1
│ ├── get-alconnector.ps1
│ ├── get-aluserassignment.ps1
│ ├── new-alicon.ps1
│ ├── get-alvcenterconnector.ps1
│ ├── Get-ALDirectory.ps1
│ ├── set-alvcenterconnector.ps1
│ ├── get-alAuditInfo.ps1
│ ├── Get-ALConnectorDetail.ps1
│ ├── get-aluserDetail.ps1
│ ├── remove-alappassignment.ps1
│ ├── get-alusergroupmembership.ps1
│ ├── remove-aloslayerrev.ps1
│ ├── Set-ALAdminUser.ps1
│ ├── remove-alapplayerrev.ps1
│ ├── get-aluserlist.ps1
│ ├── add-alappassignment.ps1
│ ├── get-alldapobject.ps1
│ ├── remove-alplatformlayerrev.ps1
│ ├── remove-alelappassignment.ps1
│ ├── invoke-allayerfinalize.ps1
│ ├── connect-alsession.ps1
│ ├── Set-ALConnectorCred.ps1
│ ├── Invoke-ALPublish.ps1
│ ├── new-alapplayerclone.ps1
│ ├── Export-allayerrev.ps1
│ ├── Import-allayerrev.ps1
│ ├── test-aldirectory.ps1
│ ├── Set-ALOslayer.ps1
│ ├── Set-ALPlatformlayer.ps1
│ ├── add-alelappassignment.ps1
│ ├── test-aldirectoryauth.ps1
│ └── set-alapplayer.ps1
└── Private
│ ├── Test-ALWebsession.ps1
│ └── Test-ALRemoteFileShare.ps1
├── AppVeyor
├── helpers.ps1
├── builddocs.ps1
└── deploy.ps1
├── LICENSE
└── appveyor.yml
/.GITIGNORE:
--------------------------------------------------------------------------------
1 | .vscode
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Examples/README.MD:
--------------------------------------------------------------------------------
1 | Check out https://www.techdrabble.com/citrix/app-layering/34-automating-app-and-os-layers for usage
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | patreon: ryancbutler
4 | custom: ["https://paypal.me/ryancbutler","https://www.buymeacoffee.com/ryancbutler"]
5 |
--------------------------------------------------------------------------------
/docs/use/use_loadadmin.md:
--------------------------------------------------------------------------------
1 | # Local Users
2 |
3 | ## Get Local Users
4 |
5 | ```powershell
6 | Get-ALLocalUser -websession $websession
7 | ```
8 |
9 | ## Set Local Admin Password
10 |
11 | ```powershell
12 | Set-ALAdminUser -websession $websession -Password $PlainPassword -Verbose
13 | ```
--------------------------------------------------------------------------------
/docs/use/use_systeminfo.md:
--------------------------------------------------------------------------------
1 | # System Info
2 |
3 | ## Get System Information (Version)
4 |
5 | ```powershell
6 | Get-ALSystemInfo -websession $websession
7 | ```
8 |
9 | ## Get System Settings
10 |
11 | ```powershell
12 | get-alsystemsettinginfo -websession $websession|Select-Object -ExpandProperty value -Property @{Name="SettingName"; Expression = {$_.Name}}
13 | ```
--------------------------------------------------------------------------------
/Tests/ctxal-sdk.tests.ps1:
--------------------------------------------------------------------------------
1 | Describe 'Module Metadata Validation' {
2 | it 'Script fileinfo should be ok' {
3 | {Test-ModuleManifest ".\ctxal-sdk\ctxal-sdk.psd1" -ErrorAction Stop} | Should -Not -Throw
4 | }
5 |
6 | it 'Import module should be ok'{
7 | {Import-Module ".\ctxal-sdk\ctxal-sdk.psm1"-Force -ErrorAction Stop} | Should -Not -Throw
8 | }
9 | }
--------------------------------------------------------------------------------
/docs/install.md:
--------------------------------------------------------------------------------
1 | # Install and Update
2 |
3 | ## Install Manually
4 |
5 | ```powershell
6 | Import-Module ".\ctxal-sdk.psm1"
7 | ```
8 |
9 | ## Install PSGallery
10 |
11 | ```powershell
12 | Find-Module -name ctxal-sdk
13 | Install-Module -Name ctxal-sdk -Scope CurrentUser
14 | ```
15 |
16 | ## Update PSGallery
17 |
18 | ```powershell
19 | Find-Module -name ctxal-sdk
20 | Update-Module -Name ctxal-sdk
21 | ```
22 | ``
--------------------------------------------------------------------------------
/docs/use/use_tasks.md:
--------------------------------------------------------------------------------
1 | # Task Status
2 |
3 | ## Get Task Status
4 | Get all tasks
5 |
6 | ```powershell
7 | Get-ALStatus -websession $websession
8 | ```
9 |
10 | Get specific task based on ID (accepts wildcard)
11 | ```powershell
12 | Get-ALStatus -id 123456 -websession $websession
13 | ```
14 |
15 | ## Cancel Task
16 | Locate ID of Task `Get-ALStatus -websession $websession`
17 |
18 | ```powershell
19 | Stop-ALWorkTicket -id 123456 -websession $websession
20 | ```
--------------------------------------------------------------------------------
/ctxal-sdk/ctxal-sdk.psm1:
--------------------------------------------------------------------------------
1 | $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue )
2 | $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue )
3 |
4 | #Dot source the files
5 | Foreach($import in @($Public + $Private))
6 | {
7 | Try
8 | {
9 | . $import.fullname
10 | }
11 | Catch
12 | {
13 | Write-Error -Message "Failed to import function $($import.fullname): $_"
14 | }
15 | }
--------------------------------------------------------------------------------
/docs/use/use_connect.md:
--------------------------------------------------------------------------------
1 | # Connect and Disconnect
2 |
3 | ## Connect
4 |
5 | ```powershell
6 | $aplip = "192.168.1.5"
7 | $pass = "Password"
8 | $username = "administrator"
9 | $SecurePassword = ConvertTo-SecureString $Pass -AsPlainText -Force
10 | $Credential = New-Object System.Management.Automation.PSCredential ($Username, $SecurePassword)
11 | $websession = Connect-alsession -aplip $aplip -Credential $Credential -Verbose
12 | ```
13 |
14 | ## Disconnect
15 |
16 | ```powershell
17 | disconnect-alsession -websession $websession
18 | ```
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SOURCEDIR = .
8 | BUILDDIR = .
9 |
10 | # Put it first so that "make" without argument is like "make help".
11 | help:
12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
13 |
14 | .PHONY: help Makefile
15 |
16 | # Catch-all target: route all unknown targets to Sphinx using the new
17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
18 | %: Makefile
19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | Citrix App Layering PowerShell SDK (BETA)
2 | =========================================
3 |
4 | This is a reversed engineered SDK that emulates the SOAP calls that AL uses to manage the appliance. Currently only supports version **4.11 or later**. **THIS USES UNSUPPORTED API CALLS. PLEASE USE WITH CAUTION.**
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 | :hidden:
9 | :caption: Getting Started
10 |
11 | install
12 | changelog
13 |
14 | .. toctree::
15 | :maxdepth: 2
16 | :hidden:
17 | :glob:
18 | :caption: Command Help
19 |
20 | cmd/*
21 |
22 | .. toctree::
23 | :maxdepth: 2
24 | :hidden:
25 | :glob:
26 | :caption: Usage Examples
27 |
28 | use/*
--------------------------------------------------------------------------------
/AppVeyor/helpers.ps1:
--------------------------------------------------------------------------------
1 | Function Test-Encoding
2 | {
3 | [CmdletBinding()]
4 | Param (
5 | [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
6 | [string]$Path
7 | )
8 | $contents = new-object byte[] 3
9 | $stream = [System.IO.File]::OpenRead($path)
10 | $stream.Read($contents, 0, 3)|out-null
11 | $stream.Close()
12 | ($contents[0] -eq 0x66 -and $contents[1] -eq 0x75 -and $contents[2] -eq 0x6E) -or ($contents[0] -eq 0x20 -and $contents[1] -eq 0x66 -and $contents[2] -eq 0x75) -or ($contents[0] -eq 0x24 -and $contents[1] -eq 0x50 -and $contents[2] -eq 0x75) -or ($contents[0] -eq 70 -and $contents[1] -eq 117 -and $contents[2] -eq 110)
13 |
14 | }
--------------------------------------------------------------------------------
/docs/use/use_icons.md:
--------------------------------------------------------------------------------
1 | # Icons
2 |
3 | ## Get icon ids
4 |
5 | ```powershell
6 | Get-ALicon -websession $websession
7 | ```
8 |
9 | ## Export all icons (save as png)
10 |
11 | ```powershell
12 | $icons = Get-ALicon -websession $websession
13 |
14 | foreach($icon in $icons)
15 | {
16 | #No authentication needed to grab image
17 | Invoke-WebRequest -uri $($icon.url) -OutFile ("D:\Temp\icons\" + $($icon.iconid)+".png")
18 | }
19 | ```
20 |
21 | ## Get icon associations
22 |
23 | ```powershell
24 | Get-ALiconassoc -websession $websession -iconid "196608"
25 | ```
26 |
27 | ## Create new icon
28 |
29 | ```powershell
30 | $iconfile = "D:\Temp\icons\myiconpic.png"
31 | $temp = new-alicon -WebSession $websession -iconfile $iconfile -Verbose
32 | ```
33 |
34 | ## Remove icon
35 |
36 | ```powershell
37 | Remove-ALicon -websession $websession -iconid "4259840"
38 | ```
--------------------------------------------------------------------------------
/ctxal-sdk/Public/Get-ALVMName.ps1:
--------------------------------------------------------------------------------
1 | function Get-ALVMName {
2 | <#
3 | .SYNOPSIS
4 | Extracts VM name out of "action required" task
5 | .DESCRIPTION
6 | Extracts VM name out of "action required" task
7 | .PARAMETER message
8 | Message from pending operation
9 | .EXAMPLE
10 | Get-ALVMName -message $status.WorkItems.WorkItemResult.Status
11 | #>
12 | [cmdletbinding()]
13 | Param(
14 | [Parameter(Mandatory = $true)]$message
15 | )
16 | Begin {
17 | Write-Verbose "BEGIN: $($MyInvocation.MyCommand)"
18 | #Test-ALWebsession -WebSession $websession
19 | }
20 | Process {
21 | $pattern = "(?<=(\]|'))([^'\[]*)-\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d.\d\d\d([^\[']*)(?=(\[|'))"
22 | $result = [regex]::match($message, $pattern)
23 | Write-Verbose $result
24 | return $result.value
25 | }
26 | end { Write-Verbose "END: $($MyInvocation.MyCommand)" }
27 | }
28 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=.
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/ctxal-sdk/Private/Test-ALWebsession.ps1:
--------------------------------------------------------------------------------
1 | function Test-ALWebsession {
2 | <#
3 | .SYNOPSIS
4 | Tests for valid web request session
5 | .DESCRIPTION
6 | Tests for valid web request session
7 | .PARAMETER websession
8 | Existing Webrequest session for ELM Appliance
9 | .EXAMPLE
10 | Test-ALWebsession -websession $websession
11 | #>
12 | [cmdletbinding()]
13 | [OutputType([System.boolean])]
14 | Param(
15 | [Parameter(Mandatory = $true)]$websession
16 | )
17 | Begin {
18 | Write-Verbose "BEGIN: $($MyInvocation.MyCommand)"
19 | }
20 | Process {
21 |
22 | if ([string]::IsNullOrWhiteSpace($websession.token)) {
23 | throw "Not Connected. Run Connect-ALSession to connect"
24 | }
25 | else {
26 | Write-Verbose "Connection OK"
27 | #return $true
28 | }
29 |
30 | }
31 | end { Write-Verbose "END: $($MyInvocation.MyCommand)" }
32 | }
--------------------------------------------------------------------------------
/AppVeyor/builddocs.ps1:
--------------------------------------------------------------------------------
1 | Import-Module -Name "$env:APPVEYOR_BUILD_FOLDER\ctxal-sdk" -Force -Verbose
2 | $verbs = (Get-Command -Module ctxal-sdk).Verb | Select-Object -Unique
3 |
4 | $TextInfo = (Get-Culture).TextInfo
5 | $title = $TextInfo.ToTitleCase($verb)
6 | foreach ($verb in $verbs)
7 | {
8 | $data = @()
9 | $data += "$title Commands"
10 | $data += '========================='
11 | $data += ''
12 | $data += "This page contains details on **$title** commands."
13 | $data += ''
14 | foreach ($help in (Get-Command -Module ctxal-sdk| Where-Object -FilterScript {
15 | $_.name -like "$verb-*"
16 | }))
17 | {
18 | $data += $help.Name
19 | $data += '-------------------------'
20 | $data += ''
21 | $data += Get-Help -Name $help.name -Detailed
22 | $data += ''
23 | }
24 |
25 | $data | Out-File -FilePath "$env:APPVEYOR_BUILD_FOLDER\docs\cmd\cmd_$($verb.ToLower()).rst" -Encoding utf8
26 | Write-Output " cmd_$($verb.ToLower())"
27 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Ryan Butler
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/changelog.rst:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========================
3 | - 06-01-2018 BETA release
4 | - 06-03-2018 Function for appliance details
5 | - 06-03-2018 Fix in Get-alvmname for message text
6 | - 06-04-2018 Get system info functions
7 | - 06-09-2018 Better response output and clarify examples
8 | - 06-20-2018 Get-ALImageComp function add
9 | - 10-05-2018 Add stop-alworkticket function
10 | - 10-18-2018 Add XenServer OS import option (now vcenter and xenserver)
11 | - 10-18-2018 More detail for Get-ALImageComp
12 | - 10-30-2018 Added functionality to export, view, create, check associations and remove icons
13 | - 11-08-2018 Added functionality to export and import layers to and from network shares
14 | - 11-10-2018 Cleaned up parameters and better get status returns
15 | - 12-29-2018 Added functionality for directory junctions
16 | - 01-22-2019 Added functionality to pull user information and assignments
17 | - 01-22-2019 Much better regex for Get-AlVMName (Thanks Bill Nickerson @wnickerson78)
18 | - 01-29-2019 Added ability to remove layer revisions (Thanks Siebrand Feenstra @Siebrandf)
19 | - 02-18-2019 Added better functionality to see app assignments (See Examples\GetUserAppAssignments)
20 | - 02-21-2019 vCenter Connector commands
21 | - 04-01-2019 Set admin password functionality. Get local accounts
22 | - 04-11-2019 Get connector detail and set connector credentials
--------------------------------------------------------------------------------
/ctxal-sdk/Public/disconnect-alsession.ps1:
--------------------------------------------------------------------------------
1 | function Disconnect-ALsession {
2 | <#
3 | .SYNOPSIS
4 | Logs off and disconnects web session
5 | .DESCRIPTION
6 | Logs off and disconnects web session
7 | .PARAMETER websession
8 | Existing Webrequest session for ELM Appliance
9 | .EXAMPLE
10 | Disconnect-ALsession -websession $websession
11 | #>
12 | [cmdletbinding()]
13 | Param(
14 | [Parameter(Mandatory = $true)]$websession
15 |
16 | )
17 | Begin {
18 | Write-Verbose "BEGIN: $($MyInvocation.MyCommand)"
19 | Test-ALWebsession -WebSession $websession
20 | }
21 | Process {
22 | [xml]$xml = @"
23 |
24 |
25 |
26 |
27 |
28 | "@
29 | Write-Verbose $xml
30 | $headers = @{
31 | "Content-Type" = "text/xml; charset=utf-8";
32 | UNIDESK_TOKEN = $websession.token;
33 | SOAPAction = "http://www.unidesk.com/Logout";
34 | }
35 | $url = "https://" + $websession.aplip + "/Unidesk.Web/API.asmx"
36 | Invoke-WebRequest -Uri $url -Method Post -Body $xml -Headers $headers -WebSession $websession | Out-Null
37 | }
38 | end { Write-Verbose "END: $($MyInvocation.MyCommand)" }
39 | }
40 |
--------------------------------------------------------------------------------
/docs/cmd/cmd_disconnect.rst:
--------------------------------------------------------------------------------
1 | Commands
2 | =========================
3 |
4 | This page contains details on **** commands.
5 |
6 | Disconnect-ALsession
7 | -------------------------
8 |
9 |
10 | NAME
11 | Disconnect-ALsession
12 |
13 | SYNOPSIS
14 | Logs off and disconnects web session
15 |
16 |
17 | SYNTAX
18 | Disconnect-ALsession [-websession]