Posts RSS Comments RSS 253 Posts and 407 Comments till now

blog: Import/Export XenApp Applications with Powershell

If there is one functionality that has been requested from myself and Citrix it is the ability to import/export applications.

With the XenApp cmdlets this is super trivial.

This is the SUPER COMPLEX Script ;)

Get-XAApplication -full | Export-Clixml .MyApps.txt
# Make sure the Apps are as you want
Import-Clixml .MyApps.txt
# To Import
Import-Clixml .MyApps.txt| New-XAApplication
# Lets see what apps we have now (I added the Imported)
Get-XAApplication | select BrowserName

Not at all complex is it? Great stuff.

Here is a demo that shows how to do it.
Download XenAppExport Demo

blog: New XenApp cmdlets demo from Synergy

I have to say… the XenApp guys at Citrix get it and I mean they really get it. We all know there are areas where Citrix has blew it in the Powershell space, but this is not one of them (good time to note that Citrix has taken the feedback from the community and is changing things.)

btw… You can catch a vid of me and Brian Madden discussing Powershell HERE. If I sound a tad distracted… I am. This was done in the Expo hall with 1000s of people walking around. I was doing my best not to yell out ";LOOK!… SHINY!";

I had the privilege of showing off the new XenApp cmdlets to the world at Synergy and thought I would share the demo's with you guys as well.

Ok… back to the blog at hand :)

NOTE: It requires 4.5 with HR3 and above for most functionality. XenApp5 for full functionality.

Here is the first demo that demo's Get-XAFarm, Get-XAFarmConfiguration, Get-XAServer, and Get-XAApplication

Download XenAppDemo

Here is the list of the cmdlets included, sorted by verb:

Verb: Add
Name
—-
Add-XAAdministratorPrivilege
Add-XAApplicationAccount
Add-XAApplicationFileType
Add-XAApplicationServer
Add-XALoadEvaluatorServer
Add-XASessionPrinter

Verb: Clear
Name
—-
Clear-XAConfigurationLog

Verb: Connect
Name
—-
Connect-XASession

Verb: Copy
Name
—-
Copy-XAApplication

Verb: Disable
Name
—-
Disable-XAAdministrator
Disable-XAApplication
Disable-XAPolicy
Disable-XAServerLogOn

Verb: Disconnect
Name
—-
Disconnect-XASession

Verb: Enable
Name
—-
Enable-XAAdministrator
Enable-XAApplication
Enable-XAPolicy
Enable-XAServerLogOn

Verb: Get
Name
—-
Get-XAAccount
Get-XAAccountAuthority
Get-XAAdministrator
Get-XAAdministratorFolder
Get-XAAdministratorPrivilege
Get-XAApplication
Get-XAAppliedPolicy
Get-XAAutoReplicatedPrinterDriver
Get-XAClientModule
Get-XAClientPrinter
Get-XAConfigurationLog
Get-XAFarm
Get-XAFarmConfiguration
Get-XAFileType
Get-XAFolder
Get-XAHmrTest
Get-XAIconStream
Get-XALoadEvaluator
Get-XAMemoryOptimization
Get-XAOfflineLicense
Get-XAPolicy
Get-XAPolicyConfiguration
Get-XAPolicyFilter
Get-XAPrinter
Get-XAPrinterDriver
Get-XAPrinterDriverCompatibility
Get-XAPrinterDriverMapping
Get-XAPrintServer
Get-XAProfileApplication
Get-XAResultantPolicy
Get-XAServer
Get-XAServerConfiguration
Get-XAServerLoad
Get-XASession
Get-XASessionPrinter
Get-XASessionProcess
Get-XAStreamingSession
Get-XAVirtualIPRange
Get-XAZone

Verb: Import
Name
—-
Import-XALegacyApplication
Import-XAPrintServer

Verb: Move
Name
—-
Move-XAApplication
Move-XAFolder
Move-XAServer

Verb: New
Name
—-
New-XAAdministrator
New-XAApplication
New-XAAutoReplicatedPrinterDriver
New-XAClientPrinter
New-XAFolder
New-XAHmrTest
New-XAIcaFile
New-XALoadEvaluator
New-XAPolicy
New-XAPrinterDriverCompatibility
New-XAPrinterDriverMapping
New-XAVirtualIPRange

Verb: Remove
Name
—-
Remove-XAAdministrator
Remove-XAAdministratorPrivilege
Remove-XAApplication
Remove-XAApplicationAccount
Remove-XAApplicationFileType
Remove-XAApplicationServer
Remove-XAAutoReplicatedPrinterDriver
Remove-XAClientPrinter
Remove-XAFolder
Remove-XAHmrTest
Remove-XALoadEvaluator
Remove-XALoadEvaluatorServer
Remove-XAPolicy
Remove-XAPrinterDriverCompatibility
Remove-XAPrinterDriverMapping
Remove-XAPrintServer
Remove-XAServer
Remove-XASessionPrinter
Remove-XAVirtualIPRange

Verb: Rename
Name
—-
Rename-XAApplication
Rename-XAFolder
Rename-XAHmrTest
Rename-XALoadEvaluator
Rename-XAPolicy
Rename-XAZone

Verb: Replicate
Name
—-
Replicate-XAPrinterDriver

Verb: Reset
Name
—-
Reset-XAClientPrinter

Verb: Send
Name
—-
Send-XASessionMessage

Verb: Set
Name
—-
Set-XAAdministrator
Set-XAAdministratorFolder
Set-XAApplication
Set-XAFarmConfiguration
Set-XAHmrTest
Set-XALoadEvaluator
Set-XAPolicy
Set-XAPolicyConfiguration
Set-XAPolicyFilter
Set-XAPrinterDriverCompatibility
Set-XAPrinterDriverMapping
Set-XAServerConfiguration
Set-XAServerEdition
Set-XAServerZone
Set-XASessionPrinter

Verb: Stop
Name
—-
Stop-XASession
Stop-XASessionProcess

Verb: Test
Name
—-
Test-XAConfigurationLog
Test-XALicenseServer

Verb: Update

Name
—-
Update-XAFileType
Update-XAPrinter

blog: XenDesktop Demo

While I focused most of my time on the XenApp cmdlets I did do a demo of the XenDesktop cmdlets.

Click HERE to download.

Import/Export XenApp Applications with Powershell

If there is one functionality that has been requested from myself and Citrix it is the ability to import/export applications.

With the XenApp cmdlets this is super trivial.

This is the SUPER COMPLEX Script ;)

Get-XAApplication -full | Export-Clixml .\MyApps.txt
# Make sure the Apps are as you want
Import-Clixml .\MyApps.txt
# To Import
Import-Clixml .\MyApps.txt| New-XAApplication
# Lets see what apps we have now (I added the Imported)
Get-XAApplication | select BrowserName

Not at all complex is it? Great stuff.

Here is a demo that shows how to do it.
Download XenAppExport Demo

New XenApp cmdlets demo from Synergy

I have to say… the XenApp guys at Citrix get it and I mean they really get it. We all know there are areas where Citrix has blew it in the Powershell space, but this is not one of them (good time to note that Citrix has taken the feedback from the community and is changing things.)

btw… You can catch a vid of me and Brian Madden discussing Powershell HERE. If I sound a tad distracted… I am. This was done in the Expo hall with 1000s of people walking around. I was doing my best not to yell out “LOOK!… SHINY!”

I had the privilege of showing off the new XenApp cmdlets to the world at Synergy and thought I would share the demo’s with you guys as well.

Ok… back to the blog at hand :)

NOTE: It requires 4.5 with HR3 and above for most functionality. XenApp5 for full functionality.

Here is the first demo that demo’s Get-XAFarm, Get-XAFarmConfiguration, Get-XAServer, and Get-XAApplication

Download XenAppDemo

Here is the list of the cmdlets included, sorted by verb:

Verb: Add
Name
—-
Add-XAAdministratorPrivilege
Add-XAApplicationAccount
Add-XAApplicationFileType
Add-XAApplicationServer
Add-XALoadEvaluatorServer
Add-XASessionPrinter

Verb: Clear
Name
—-
Clear-XAConfigurationLog

Verb: Connect
Name
—-
Connect-XASession

Verb: Copy
Name
—-
Copy-XAApplication

Verb: Disable
Name
—-
Disable-XAAdministrator
Disable-XAApplication
Disable-XAPolicy
Disable-XAServerLogOn

Verb: Disconnect
Name
—-
Disconnect-XASession

Verb: Enable
Name
—-
Enable-XAAdministrator
Enable-XAApplication
Enable-XAPolicy
Enable-XAServerLogOn

Verb: Get
Name
—-
Get-XAAccount
Get-XAAccountAuthority
Get-XAAdministrator
Get-XAAdministratorFolder
Get-XAAdministratorPrivilege
Get-XAApplication
Get-XAAppliedPolicy
Get-XAAutoReplicatedPrinterDriver
Get-XAClientModule
Get-XAClientPrinter
Get-XAConfigurationLog
Get-XAFarm
Get-XAFarmConfiguration
Get-XAFileType
Get-XAFolder
Get-XAHmrTest
Get-XAIconStream
Get-XALoadEvaluator
Get-XAMemoryOptimization
Get-XAOfflineLicense
Get-XAPolicy
Get-XAPolicyConfiguration
Get-XAPolicyFilter
Get-XAPrinter
Get-XAPrinterDriver
Get-XAPrinterDriverCompatibility
Get-XAPrinterDriverMapping
Get-XAPrintServer
Get-XAProfileApplication
Get-XAResultantPolicy
Get-XAServer
Get-XAServerConfiguration
Get-XAServerLoad
Get-XASession
Get-XASessionPrinter
Get-XASessionProcess
Get-XAStreamingSession
Get-XAVirtualIPRange
Get-XAZone

Verb: Import
Name
—-
Import-XALegacyApplication
Import-XAPrintServer

Verb: Move
Name
—-
Move-XAApplication
Move-XAFolder
Move-XAServer

Verb: New
Name
—-
New-XAAdministrator
New-XAApplication
New-XAAutoReplicatedPrinterDriver
New-XAClientPrinter
New-XAFolder
New-XAHmrTest
New-XAIcaFile
New-XALoadEvaluator
New-XAPolicy
New-XAPrinterDriverCompatibility
New-XAPrinterDriverMapping
New-XAVirtualIPRange

Verb: Remove
Name
—-
Remove-XAAdministrator
Remove-XAAdministratorPrivilege
Remove-XAApplication
Remove-XAApplicationAccount
Remove-XAApplicationFileType
Remove-XAApplicationServer
Remove-XAAutoReplicatedPrinterDriver
Remove-XAClientPrinter
Remove-XAFolder
Remove-XAHmrTest
Remove-XALoadEvaluator
Remove-XALoadEvaluatorServer
Remove-XAPolicy
Remove-XAPrinterDriverCompatibility
Remove-XAPrinterDriverMapping
Remove-XAPrintServer
Remove-XAServer
Remove-XASessionPrinter
Remove-XAVirtualIPRange

Verb: Rename
Name
—-
Rename-XAApplication
Rename-XAFolder
Rename-XAHmrTest
Rename-XALoadEvaluator
Rename-XAPolicy
Rename-XAZone

Verb: Replicate
Name
—-
Replicate-XAPrinterDriver

Verb: Reset
Name
—-
Reset-XAClientPrinter

Verb: Send
Name
—-
Send-XASessionMessage

Verb: Set
Name
—-
Set-XAAdministrator
Set-XAAdministratorFolder
Set-XAApplication
Set-XAFarmConfiguration
Set-XAHmrTest
Set-XALoadEvaluator
Set-XAPolicy
Set-XAPolicyConfiguration
Set-XAPolicyFilter
Set-XAPrinterDriverCompatibility
Set-XAPrinterDriverMapping
Set-XAServerConfiguration
Set-XAServerEdition
Set-XAServerZone
Set-XASessionPrinter

Verb: Stop
Name
—-
Stop-XASession
Stop-XASessionProcess

Verb: Test
Name
—-
Test-XAConfigurationLog
Test-XALicenseServer

Verb: Update

Name
—-
Update-XAFileType
Update-XAPrinter

Citrix News! I have join the Citrix Technology Professional ranks!

I was notified last week, but I wanted to wait till my profile was up on the site. For those of you wondering what in the heck that is… it is basically Citrix version of the MVP program. It will allow me to interact more directly with Citrix. I am sure this will be a mutually beneficial relationship. They have made a huge stake in Powershell and I want to do my best to help direct or guide their adoption.

You can read more about the program Here.

In other news and more important to you as a reader :)

Citrix is working on a set of Powershell cmdlets for XenApp 5 (most of them should work in XenApp 4.5 if you have HR3 installed.) We have been in closed beta, but I have got to tell you… this is good stuff. They did a stellar job and have been very open to feedback. These cmdlets should make my scripts obsolete and I am very much looking forward to it. I will be releasing details and demo's as soon as I am allowed.

OH! Did I mention I am doing a Geek Speak Session at Synergy? Well I am!

At this point I just know I am on Wednesday at some time, but I will be there all week if you around. Just email!

Lets show them we Powershell people are serious! Vote for my session here: VOTE!

Citrix News! I have join the Citrix Technology Professional ranks!

I was notified last week, but I wanted to wait till my profile was up on the site. For those of you wondering what in the heck that is… it is basically Citrix version of the MVP program. It will allow me to interact more directly with Citrix. I am sure this will be a mutually beneficial relationship. They have made a huge stake in Powershell and I want to do my best to help direct or guide their adoption.

You can read more about the program Here.

In other news and more important to you as a reader :)

Citrix is working on a set of Powershell cmdlets for XenApp 5 (most of them should work in XenApp 4.5 if you have HR3 installed.) We have been in closed beta, but I have got to tell you… this is good stuff. They did a stellar job and have been very open to feedback. These cmdlets should make my scripts obsolete and I am very much looking forward to it. I will be releasing details and demo’s as soon as I am allowed.

OH! Did I mention I am doing a Geek Speak Session at Synergy? Well I am!

At this point I just know I am on Wednesday at some time, but I will be there all week if you around. Just email!

Lets show them we Powershell people are serious! Vote for my session here: VOTE!

Tracing LDAP calls with Powershell

Spat had an eerily coincidental blog post the other day (HERE). The reason I say eerily is because the night before I was fighting trying to get a LDAP trace, this trace was to help figure out EXACTLY how SDS.ActiveDirectory got replication cursors from a Domain Controller (another joe Richards discussion.) Anyway, I digress, I found the blog entry EXTREMELY useful as it allowed me to get what I needed. I proceeded to leave a comment suggesting that this looked like a good job for Powershell as the resulting file from the tool is a CSV. This has led to a “challenge” from Spat and this is my response. I hope I did it justice.

Useful Links about Tracelog.exe
———–
Details about TraceLog.exe
LDAP tracing with TraceLog
ADSI tracing with TraceLog

Details about Script

Here are the functions in the script

Trace-Log
-flag: Hex value for the flags you want to pass (Default Value = “0x1FFFDFF3″)
-guid: GUID or File for tracing (Default Value = “LDAP”)
-SessionName: Unique Name for the actual trace (Default Value = “mytrace”)
-exe: The full name with extension of the EXE to add to registry to enable tracing. This only has to be done the first time you want to trace for an EXE.
[switch]Start: If set it enables logging. If not set, logging is disabled.
[switch]ADSI: If set it passes the ADSI GUID for tracing
[switch]LDAP: If set it passes the ADSI GUID for tracing

Convert-TraceLog
-Source: Trace (etl) file to convert to csv (Default Value = “.\ldap.etl”)
-file: File to set the results to (Default Value = “TraceResults.csv”)
[switch]$import: If set it will return a custom object with results

Below is a video that shows a demo of the script in use. I hope to do another one of these showing how to trace ADSI as well as LDAP. Make sure to read the Comments in Green. I tried to allow enough time. You can click to pause.

Download Tracelog Transcript (right click | Save Target As…)
Best Viewed Full Screen

Get the Flash Player to see this content.

Code
Download Trace Log Functions (right click | Save Target As…)

function Trace-Log {
    Param($file = ".\ldap.etl",
        $flag = 0x1FFFDFF3,
        $guid = "LDAP",
        $SessionName = "mytrace",
        $exe,
        [switch]$start,
        [switch]$ADSI,
        [switch]$LDAP
    )
    if($ADSI){$guid = "ADSI"}
    switch -exact ($guid)
    {
        "LDAP"  {$myguid = ‘#099614a5-5dd7-4788-8bc9-e29f43db28fc’}
        "ADSI"  {$myguid = ‘#7288c9f8-d63c-4932-a345-89d6b060174d’}
        Default {$myguid = "’$_’"}
    }
   
    Write-Host
   
    if($start)
    {
        Write-Host " Action: Start" -fore Yellow
        Write-Host " GUID:   $GUID" -fore Yellow
        Write-Host " File:   $file" -fore Yellow
        Write-Host " Flag:   $flag" -fore Yellow
        if($exe){Write-Host " Exe:    $exe" -fore Yellow}
       
    }
    else
    {
        Write-Host " State: Disabled" -fore Red
    }
   
    Write-Host
   
    if(!(test-Path "HKLM:\System\CurrentControlSet\Services\ldap\tracing\$exe") -and $exe)
    {
        new-Item -path "HKLM:\System\CurrentControlSet\Services\ldap\tracing" -name $exe | out-Null
    }
   
    if($start)
    {
        $cmd = "Tracelog.exe -start ‘$SessionName’ -f ‘$file’ -flag ‘$flag’ -guid ‘$myguid’"
    }
    else
    {
        $cmd = "tracelog -stop $SessionName"
    }
   
    Write-Host
    Write-Host "==========================" -fore White -back black
    write-Host "Running Command:" -fore White
    Write-Host " ==> $cmd" -fore Yellow
    invoke-Expression $cmd
    Write-Host "==========================" -fore White -back black
    Write-Host
}
function Convert-TraceFile{
    Param($Source=".\ldap.etl",$file="TraceResults.csv",[switch]$import)
   
    $cmd = "tracerpt.exe $Source -o $file -of CSV -y"
   
    invoke-Expression $cmd
   
    if($import)
    {
        import-Csv $file
    }
}

Test-Host (WMI Ping -or Port Check)

I often find (specifically when using WMI) the need to ping the machine first before performing any queries. WMI takes FOREVER to timeout. I decided that I should use a script/function to test a host before passing it down the pipe.

There are a couple of problems with this approach that I had to consider.
1) How do I know what to test without corrupting the pipe or using foreach?
- For this I added a “-property” parameter that would allow the user to pick what property to check against, but still output the entire object that was inputted.

2) What about firewalls that block ping?
- Added TestPort function that does a TCP connect and returns $true or $false

3) What if I want a conditional port check.
- Added the ability to Change the Default Port for TCP Connection Test

Here is the script that I came up with and some of things it does.
Parameters
- $property: The Property to Ping or Test (Default is none.)
- $tport: The Port to test against (Default is 135. Used with -port)
- $timeout: The timeout for the connection (Default is 1000 ms, Used with -port)
- [switch]$port: Switch to Test a port instead of Ping
- [switch]$verbose: Provides Verbose Output.
Features
- Will Ping ‘$_’ by default
- Can pass the property that contains the Host to test using -property
- Can use -port to test a port instead of ping. (Uses TCP)
- Maintains the Object that is tested and passes it down the pipe if connection is passed.

A Demo of the script in action

Best Viewed Full Screen

Get the Flash Player to see this content.


Script CODE

Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
Begin{
    function TestPort {
        Param($srv)
        $error.Clear()
        $ErrorActionPreference = "SilentlyContinue"
        $tcpclient = new-Object system.Net.Sockets.TcpClient
        $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
        $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
        # Traps    
        trap {if($verbose){Write-Host "General Exception"};return $false}
        trap [System.Net.Sockets.SocketException]
        {
            if($verbose){Write-Host "Exception: $($_.exception.message)"}
            return $false
        }
        if(!$wait)
        {
            $tcpclient.Close()
            if($verbose){Write-Host "Connection Timeout"}
            return $false
        }
        else
        {
            $tcpclient.EndConnect($iar) | out-Null
            $tcpclient.Close()
        }
        if(!$error[0]){return $true}
    }
    function PingServer {
        Param($MyHost)
        $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
        if($pingresult.statuscode -eq 0) {$true} else {$false}
    }
}
Process{
    if($_)
    {
        if($port)
        {
            if($property)
            {
                if(TestPort $_.$property){$_}  
            }
            else
            {
                if(TestPort $_){$_}
            }
        }
        else
        {
            if($property)
            {
                if(PingServer $_.$property){$_}  
            }
            else
            {
                if(PingServer $_){$_}
            }
        }
    }
}

If you want this as a function use this code

function Test-Host{
Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
Begin{
    function TestPort {
        Param($srv)
        $error.Clear()
        $ErrorActionPreference = "SilentlyContinue"
        $tcpclient = new-Object system.Net.Sockets.TcpClient
        $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
        $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
        # Traps    
        trap {if($verbose){Write-Host "General Exception"};return $false}
        trap [System.Net.Sockets.SocketException]
        {
            if($verbose){Write-Host "Exception: $($_.exception.message)"}
            return $false
        }
        if(!$wait)
        {
            $tcpclient.Close()
            if($verbose){Write-Host "Connection Timeout"}
            return $false
        }
        else
        {
            $tcpclient.EndConnect($iar) | out-Null
            $tcpclient.Close()
        }
        if(!$error[0]){return $true}
    }
    function PingServer {
        Param($MyHost)
        $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
        if($pingresult.statuscode -eq 0) {$true} else {$false}
    }
}
Process{
    if($_)
    {
        if($port)
        {
            if($property)
            {
                if(TestPort $_.$property){$_}  
            }
            else
            {
                if(TestPort $_){$_}
            }
        }
        else
        {
            if($property)
            {
                if(PingServer $_.$property){$_}  
            }
            else
            {
                if(PingServer $_){$_}
            }
        }
    }
}}

Get-CitrixApplication (Playing Around Series)

Here is a quick demo of getting a Citrix Application and playing with its properties.

Best Viewed Full Screen

Get the Flash Player to see this content.


Demo File

#
# First we need to create the MFCOM Object
#
$mfapp = new-object -com MetaFrameCom.MetaFrameApplication
#
# To initialize we need to pass the app we want to accesss
#
$mfapp.Initialize(3,"Applications\Powershell")
#
# With Applications we need to load the data
#
$mfapp.loaddata(1)
#
# Lets see what we have
#
$mfapp | Get-Member -type Properties
#
# Lets look at Users and Groups
#
$mfapp | select Users,Groups
#
# How bout Servers
#
$mfapp.Servers | Select ServerName
#
# Sessions?
#
$mfApp.Sessions | ft SessionID,AppName,ClientAddress,ClientHRes,ClientVRes -auto

Next »