Friday, May 1, 2015

Further automating GoToMeeting on a Windows client

To continue to build on my previous post I decided to add a bit of id10t proofing to my automation script.

The only thing that the script does not do is logon the user (I mean, who really wants to handle (secure) user credentials in the first place).

This is here for my benefit, but I am sure that this can be useful to someone else.  There is nothing here that I did not discover through internet search or my own discovery.

I don't register an event monitor for a simple reason, I cannot guarantee that the execution of this program has admin rights.  Admin access on the local computer is required to register for an event, though it would be nice for a user to be able to register for user mode process events.


    This will install the full G2M client for hosting meetings if it is not already installed prior to joining the meeting.
    $g2mId - the meeting ID that will be joined. This can be any g2m ID, the user will be 'joining' an existing meeting (theirs or someone else's).
    $g2mKill - if there is a G2M already running that will be killed and the passed G2M will be joined.
    Brian Ehlert, Citrix Labs, Redmond, WA

function startG2m

    [parameter(Mandatory = $false)]
    [parameter(Mandatory = $false)]
    [boolean]$g2mKill = $false

    # finds the path of g2mstart.exe
    # each version is in its own folder so you have to find the latest / most recent version
    $gtmFolder = Get-ChildItem -Path $env:LOCALAPPDATA\Citrix\GotoMeeting -ErrorAction SilentlyContinue | Sort-Object -Property Name -Descending | Select-Object -First 1

    if ( !($gtmFolder) ) {
        "G2M is _not_ installed. Installing the hosting client."
        # Install the GTM client
        Start-Process ""

        Start-Sleep -Seconds 2
        # close the IE tab that was opened
        $ie = (New-Object -COM "Shell.Application").Windows() | where { $_.Name -eq "Internet Explorer" }

        foreach ($tab in $ie) {
            if ( $tab.LocationURL -match "" ) {
                do {
                    Start-Sleep -Seconds 1
                } until ( $tab.Busy -eq $false )

        # wait for the client logon prompt
        Do { Start-Sleep -Seconds 2 } until ( Get-Process -Name "g2mlauncher" -ErrorAction SilentlyContinue )

        startG2m -g2mId $g2mId
    } else {
        # is there an existing G2M that needs to be killed?
        # if we reconnect to the same meeting too quickly we will have ourself as an orphaned attendee.
        if ($g2mKill) {
            if ((Get-Process -Name "g2mui" -ErrorAction SilentlyContinue)) {
                "Killing the running G2M"
                Get-Process -Name "g2mui" | Stop-Process -Force
                Do { Start-Sleep -Seconds 2 } until ((Get-Process -Name g2mlauncher -ErrorAction SilentlyContinue).Handles -lt 500)
            } else {"The user was not joined to a G2M"}

        "G2M is installed, using the installed client"
        # build the path
        $g2mstartPath = $gtmFolder.FullName + "\g2mstart.exe"

        # Define the arguments - double quotes is important for g2mstart.exe
        $g2mArgs = ("'/Action Join' '/MeetingID $g2mId'" ).Replace("'",'"')

        # is there a G2M video conference running?  We will collide if there is.
        if (!(Get-Process -Name "g2*conference")) {
            if ( $g2mId ){
                "Joining the meeting"
                Start-Process -FilePath $g2mstartPath -ArgumentList $g2mArgs
            } else { "No G2M ID was provided" }
        } else { "A G2M is already running" }

startG2m -g2mId 000000000 -g2mKill $true
Start-Sleep -Seconds 5  # wait for the conference to initialize
$process = Get-Process -Name "g2*conference"
Wait-Process -InputObject $process # wait for the person to end the conference
# Do something else