Posts RSS Comments RSS 117 Posts and 170 Comments till now

Back From the MVP Summit

Well… Just got back from a week in Redmond. It was awesome!

First I want to thank MS for putting this all together. It was a testament to their commitment to the community and desire to see their products succeed.

While this was my first MVP summit, I did hear several others comment on how this was the best one yet.

I was VERY lucky to have a seasoned MVP vet (Dean Wells) show me the ropes and introduce me to some of the (IMO) smartest technical people on the planet. These guys/gals are not only incredibly smart… but they were an absolute blast to hang out with.

I doubt they subscribe to my blog but I wanted to do a shout out and link their blogs/Sites

Dean Wells: Absolute Great Trainer/Consultant http://www.msetechnology.com
joe Richards (joeware): http://blog.joeware.net/
Joe Kaplan : http://www.joekaplan.net/
Brian Desmond: http://briandesmond.com/blog/default.aspx
Laura Hunter: http://www.shutuplaura.com/
Mr Hunter (Mark Arnold) : http://markarnold.blogspot.com/
Gil Kirkpatrick (NetPro): http://www.gilsblog.com/
Ulf B. Simon-Weidner’s: http://msmvps.com/blogs/UlfBSimonWeidner/Default.aspx
Tony Murray (founder activedir.org): www.ActiveDir.org Blog: http://www.open-a-socket.com/
Little Jimmy: http://www.jimmytheswede.blogspot.com/
Darren Mar-Elia (SDMSoftware): http://www.sdmsoftware.com/blog/
Princess Jorge!: http://blogs.dirteam.com/blogs/jorge/
Brett Shirley: http://blogs.msdn.com/brettsh/
Eric Fleischman: http://blogs.technet.com/efleis/default.aspx (currently VERY slow to post)

I can not tell you (literally I am under NDA :) ) How much I learned this past week.

What I can say is that for Powershell… the future is VERY BRIGHT!

The time with the Powershell Dev team was great. Again… can’t say much, but they have great plans.

I spent about 5hrs with the Active Directory team discussing their plans. If the AD Team can pull off what they have planned… OMG it is awesome. AD administration will never be the same.

The next version of SCVMM looks great.

Get-CitrixApplication.ps1 (Citrix Top 10)

This script returns Citrix Application Objects.
- With no -AppName passed it will return All application Objects
- With -AppName it will return all apps that match (regex.)

  1. # Get-CitrixApplication.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Returns Citrix Application Objects for AppName passed or RegEx
  5. Param($AppName=".*",$server=$env:ComputerName)
  6. $type = [system.Type]::GetTypeFromProgID("MetaframeCOM.MetaFrameFarm",$server)
  7. $farm = [system.Activator]::CreateInstance($type)
  8. $farm.Initialize(1)
  9. $farm.Applications | ?{($_.AppName -match $AppName) -or ($_.BrowserName -match $AppName)}

Set-CitrixServerLogon.ps1 (Citrix Top 10)

Here is a useful little script. This Creates a MFCom Server Object and disables or Enables Logons for that Server.

  1. # Set-CitrixServerLogon.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Sets the Server to Enable or Disable Logons
  5. Param($Server,[switch]$enable,[switch]$disable,[switch]$help)
  6. function HelpMe{
  7.     Write-Host
  8.     Write-Host " Set-CitrixServerLogon.ps1:" -fore Green
  9.     Write-Host "   Sets the Server to Enable or Disable Logons"
  10.     Write-Host
  11.     Write-Host " Parameters:" -fore Green
  12.     Write-Host "   -Server                  : Optional. Server to Set Logon"
  13.     Write-Host "   -Enable                  : Optional. Checks Hours of Idle Time (Default)"
  14.     Write-Host "   -Disable                 : Optional. Checks Minutes of Idle Time"
  15.     Write-Host "   -Help                    : Optional. Displays This"
  16.     Write-Host
  17.     Write-Host " Examples:" -fore Green
  18.     Write-Host "   To disable the Logon for a Server" -fore White
  19.     Write-Host "     Set-CitrixServerLogon.ps1 -server <serverName> -Disable" -fore Yellow
  20.     Write-Host
  21. }
  22.  
  23. if(!$Server -or $help){helpme;Write-Host;return}
  24.  
  25. Write-Host
  26.  
  27. Write-Host " Getting Server [$Server]"
  28. $mfsrv = New-Object -ComObject MetaFrameCOM.MetaFrameServer
  29.  
  30. Write-Host " - Initializing Server"
  31. $mfsrv.Initialize(6,$Server)
  32.  
  33. if($enable)
  34. {
  35.     Write-Host " - Setting to EnableLogon = 1"
  36.     $mfSrv.WinServerObject.EnableLogon = 1
  37. }
  38. if($disable)
  39. {
  40.     Write-Host " - Setting to EnableLogon = 0"
  41.     $mfSrv.WinServerObject.EnableLogon = 0
  42. }
  43.  
  44. Write-Host " - Server [$($mfSrv.ServerName)] is set to [$($mfSrv.WinServerObject.EnableLogon)] for EnableLogon"
  45.  
  46. Write-Host

Another option would be to remove the Apps from the Server all together.

  1. # Unpublish-CitrixServer.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Removes all App from Server
  5. Param($Server)
  6. $mfsrv = New-Object -ComObject MetaFrameCOM.MetaFrameServer
  7. $mfsrv.Initialize(6,$Server.ToUpper())
  8. $mfsrv | foreach{$_.Applications} | foreach{$_.LoadData(1);$_.RemoveServer($Server.ToUpper());$_.SaveData()}

Get-CitrixAppServer.ps1 (Citrix Top 10)

This is pretty simple script. It is actually just an adaption from my Get-CitrixApplication.ps1 script posted at the bottom. There is a moment in time when you start thinking in terms of objects and stop thinking in terms of text output you are looking for.

This will make a huge difference in productivity and take you from constantly writing scripts to interactively getting the information you are after, but until you make the transition I will continue to provide scripts that do both :)

  1. # Get-CitrixAppServer.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Gets All the Servers for Specific App
  5. Param($app)
  6. $mfApp = New-Object -ComObject MetaFrameCOM.MetaFrameApplication
  7. $mfApp.Initialize(3,$app)
  8. $mfApp.LoadData(1)
  9. $mfApp.Servers | %{$_.ServerName}

Here is the script that I use to return an Application object.

  1. # Get-CitrixApplication.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Gets a Citrix Application Object.
  5. Param($app)
  6. $mfApp = New-Object -ComObject MetaFrameCOM.MetaFrameApplication
  7. $mfApp.Initialize(3,$app)
  8. $mfApp.LoadData(1)
  9. $mfApp

Then from the commandline I would just do this
PS> Get-CitrixApplication.ps1 “Applications\MyApp1″ | %{$_.Servers} | %{$_.ServerName}

While this looks more complicated it is more versatile and easy to change. Lets say I want current User for this app instead.
PS> Get-CitrixApplication.ps1 “Applications\MyApp1″ | %{$_.Sessions} | %{$_.UserName}

Find-CitrixUser.ps1 (Citrix Top 10)

This is another script that I can use quite often. It is a simple script that queries all the sessions and returns the ones where the User matches. I made the User a RegEx search so you could do multiple users.

Name: Find-CitrixUser.ps1
Purpose: Finds where the user(s) are and outputs session info

  1. # Find-CitrixUser.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Finds where the user(s) are and out puts session info
  5. Param($user=".*",[switch]$help)
  6. function HelpMe{
  7.     Write-Host
  8.     Write-Host " Find-CitrixUser.ps1:" -fore Green
  9.     Write-Host "   Finds where the user(s) are and out puts session info"
  10.     Write-Host
  11.     Write-Host " Parameters:" -fore Green
  12.     Write-Host "   -User                  : Optional. Name of the User or RegEx (Default is all users)"
  13.     Write-Host "   -Help                  : Optional. Displays This"
  14.     Write-Host
  15.     Write-Host " Examples:" -fore Green
  16.     Write-Host "   Finds User TestMe and outputs and returns ServerName,ClientAddress, and SessionID" -fore White
  17.     Write-Host "     .\Find-CitrixUser.ps1 | ft ServerName,ClientAddress,SessionID " -fore Yellow
  18.     Write-Host
  19.     Write-Host "   Finds all Users who start with ‘Sales’ and returns UserName,ServerName, and SessionID"  -fore White
  20.     Write-Host "     .\Find-CitrixUser.ps1 `"^sales`" | ft UserName,ServerName,SessionID " -fore Yellow
  21.     Write-Host
  22.     Write-Host "   To View All properties availiable." -fore White
  23.     Write-Host "     .\Find-CitrixUser.ps1 <username> | Get-Member" -fore Yellow
  24.     Write-Host
  25. }
  26.  
  27. # Check for the Help or if
  28. if($help){helpme;Write-Host;return}
  29.  
  30. # Code to Get the Farm and Initialize
  31. $farm = New-Object -com "MetaframeCOM.MetaFrameFarm"
  32. $farm.Initialize(1)
  33.  
  34. # Get the Sessions and Parse for Users who match
  35. $farm.Sessions | ?{$_.UserName -match $user}

Get-CitrixPrinterInfo.ps1 (Citrix Top 10)

This script just collects the Printer Information from all the Servers in the Farm. It will output them to a file or you can pipe them and filter them.

Name: Get-CitrixPrinterInfo.ps1
Purpose: Gets Print Driver Info from all the Servers in the Farm and outputs to file or console

  1. # Get-CitrixPrinterInfo.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Gets Print Driver Info from all the Servers in the Farm
  5. Param($Server,$file,[Switch]$help)
  6. function HelpMe{
  7.     Write-Host
  8.     Write-Host " Get-CitrixPrinterInfo.ps1:" -fore Green
  9.     Write-Host "   Gets Print Driver Info from all the Servers in the Farm"
  10.     Write-Host
  11.     Write-Host " Parameters:" -fore Green
  12.     Write-Host "   -Server                : Optional. Server to Get Print Info From "
  13.     Write-Host "   -File                  : Optional. File Name to Export Info to"
  14.     Write-Host "   -Help                  : Optional. Displays This"
  15.     Write-Host
  16.     Write-Host " Examples:" -fore Green
  17.     Write-Host "   Gets Print Info and Exports to File" -fore White
  18.     Write-Host "     .\Get-CitrixPrinterInfo.ps1 -file MyExportFile.txt" -fore Yellow
  19.     Write-Host
  20.     Write-Host "   Gets Print Drivers from a Specific Server and outputs DriverName and SourceServer"  -fore White
  21.     Write-Host "     .\Get-CitrixPrinterInfo.ps1 <serverName> | ft DriverName,SourceServer" -fore Yellow
  22.     Write-Host
  23. }
  24.  
  25. # Check for Help Flag
  26. if($help){HelpMe;Write-Host;Return}
  27.  
  28. # Check for File
  29. if($file)
  30. {
  31.     if($server) # If -Server was passed we run check just against it and output to screen
  32.     {
  33.         $mfsrv = new-Object -com "MetaframeCOM.MetaframeServer"
  34.         $mfsrv.Initialize(6,$Server.ToUpper())
  35.         $mfsrv | foreach{"`n$($_.ServerName) `n$(’-'*20)";$_.PrinterDrivers| Format-Table} | out-File $file -enc ASCII
  36.     }
  37.     else # We run the check against the whole farm and output results to file
  38.     {
  39.         $mfarm = new-Object -com "MetaframeCOM.MetaframeFarm"
  40.         $mfarm.Initialize(1)
  41.         $mfarm.Servers | foreach{"`n$($_.ServerName) `n$(’-'*20)";$_.PrinterDrivers| Format-Table} | out-File $file -enc ASCII
  42.     }
  43. }
  44. else
  45. {
  46.     if($server) # If -Server was passed we run check just against it and output to screen
  47.     {
  48.         $mfsrv = new-Object -com "MetaframeCOM.MetaframeServer"
  49.         $mfsrv.Initialize(6,$Server.ToUpper())
  50.         $mfsrv | foreach{"`n$($_.ServerName) `n$(’-'*20)";$_.PrinterDrivers| Format-Table}
  51.     }
  52.     else # We run the check against the whole farm and output results to screen
  53.     {
  54.         $mfarm = new-Object -com "MetaframeCOM.MetaframeFarm"
  55.         $mfarm.Initialize(1)
  56.         $mfarm.Servers | foreach{"`n$($_.ServerName) `n$(’-'*20)";$_.PrinterDrivers| Format-Table}
  57.     }
  58.  }

Find-CitrixIdleUser.ps1 (Citrix Top 10)

This is one of the more useful scripts (at least for me.) It will query the farm and tell you all the user who have exceeded the idle time specified. I also combined another script that logged off users.

Name: Find-CitrixIdleUser.ps1
Purpose: Finds users with idle time greater than value passed and logs them off if -logoff is passed

  1. # Find-CitrixIdleUser.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # Finds users with idle time greater than value passed
  5. Param($time,[switch]$day,[switch]$hour,[switch]$minute,[switch]$logoff,[switch]$verbose,[switch]$help)
  6. function HelpMe{
  7.     Write-Host
  8.     Write-Host " Find-CitrixIdleUser.ps1:" -fore Green
  9.     Write-Host "   Finds users with idle time greater than value passed"
  10.     Write-Host
  11.     Write-Host " Parameters:" -fore Green
  12.     Write-Host "   -Time                  : Optional. Server to Get Print Info From "
  13.     Write-Host "   -Day                   : Optional. Checks Days of Idle Time "
  14.     Write-Host "   -Hour                  : Optional. Checks Hours of Idle Time (Default)"
  15.     Write-Host "   -Minute                : Optional. Checks Minutes of Idle Time"
  16.     Write-Host "   -Logoff                : Optional. Logs User off if Idle Time exceeds Time"
  17.     Write-Host "   -Verbose               : Optional. Show Verbose Output"
  18.     Write-Host "   -Help                  : Optional. Displays This"
  19.     Write-Host
  20.     Write-Host " Examples:" -fore Green
  21.     Write-Host "   Finds Users who have been idle 2 hours and return AppName, UserName, SessionID, and ClientName" -fore White
  22.     Write-Host "     Find-CitrixIdleUser.ps1 2 -hour | ft AppName,UserName,SessionID,ClientName -auto" -fore Yellow
  23.     Write-Host
  24.     Write-Host "   Finds Users who have been idle 2 hours and Logs them Off" -fore White
  25.     Write-Host "     Find-CitrixIdleUser.ps1 2 -hour -logoff" -fore Yellow
  26.     Write-Host
  27. }
  28. if($verbose){$verbosepreference = "Continue"}
  29. Write-Host
  30. if(!$time -or $help){helpme;Write-Host;Return}
  31.  
  32. # Get Citrix Farm Object
  33. Write-Verbose " - Creating MFFarm Object"
  34. $farm = new-Object -com "MetaframeCOM.MetaframeFarm"
  35. $farm.Initialize(1)
  36.  
  37. # Parse Sessions
  38. Write-Verbose " - Parsing Sessions. Total of [$($farm.Sessions.count)] Sessions"
  39. foreach($session in $farm.Sessions)
  40. {
  41.     Write-Verbose "   - Processing Session ID [$($Session.SessionId)]"
  42.     $shouldLogOff = $false
  43.  
  44.     # Getting Citrix Session Idle Time and Convert to System.DateTime
  45.     Write-Verbose "   - Getting LastInputTime"
  46.     $ctxDate = $session.LastInputTime(1)
  47.     Write-Verbose "   - Checking if idle time is -gt 0"
  48.     if(($ctxDate.HighPart -ne 0) -and ($ctxDate.LowPart -ne 0))
  49.     {
  50.         $date = "{0,4}{1,2:00}{2,2:00}{3,2:00}{4,2:00}" -f $ctxDate.year,$ctxDate.Month,$ctxDate.Day,$ctxDate.Hour,$ctxDate.Minute
  51.         Write-Verbose "   - Converted LastInputTime to [$date]"
  52.         $SessionIdleTime = [system.DateTime]::ParseExact($date,‘yyyyMMddHHmm’,$null)
  53.  
  54.         # Get Current Time in System.DateTime
  55.         Write-Verbose "   - Getting Current Date"
  56.         $now = Get-Date
  57.         Write-Verbose "   - Current Date is [$now]"
  58.  
  59.         # Find Difference
  60.         Write-Verbose "   + Getting Time Difference"
  61.         $diff = $now - $SessionIdleTime
  62.         Write-Verbose "     - Found Days [$($diff.TotalDays)] Hours [$($diff.Totalhours)] Minutes [$($diff.TotalMinutes)]"
  63.  
  64.         # Output Sessions that match
  65.         if($day)   {    if($diff.TotalDays    -gt $time)    {$session;$shouldLogOff = $true}  }
  66.         if($hour)  {    if($diff.Totalhours   -gt $time)    {$session;$shouldLogOff = $true}  }
  67.         if($minute){    if($diff.TotalMinutes -gt $time)    {$session;$shouldLogOff = $true}  }
  68.  
  69.         Write-Verbose "     - Set `$shouldLogOff to [$shouldLogOff]"
  70.  
  71.         # Logging Off User
  72.         if($logoff -and $shouldLogOff)
  73.         {
  74.             Write-Verbose "   - Logging Off Session ID [$($Session.SessionId)]"
  75.             $session.Logoff($false)
  76.         }
  77.     }
  78.     else
  79.     {
  80.         Write-Verbose "   - Session ID [$($Session.SessionId)] NOT Idle"
  81.     }
  82.     Write-Host
  83. }

Get-CitrixSessionUser.ps1 (Citrix Top 10)

One of the script I was asked to convert was a script to output all the Users and the Client IP.

This is what I came up with

Name: Get-CitrixSessionUser.ps1
Purpose: List ClientAddress and UserName for each Session

  1. # Get-CitrixSessionUser.ps1
  2. # Brandon Shell [MVP]
  3. # www.bsonposh.com
  4. # List ClientAddress and UserName for each