Posts RSS Comments RSS 117 Posts and 170 Comments till now

Archive for May, 2008

Looking for interesting Citrix Problems

I am working on some blog entries and content for Citrix CDN and was curious what you guys thought.

If you have time, please leave some comments on problems or suggestions of things you would like to see. Specifically I am looking for some “real” world scenarios that I can present and provide solutions for.

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 player.

Script CODE

  1. Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
  2. Begin{
  3.     function TestPort {
  4.         Param($srv)
  5.         $error.Clear()
  6.         $ErrorActionPreference = "SilentlyContinue"
  7.         $tcpclient = new-Object system.Net.Sockets.TcpClient
  8.         $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
  9.         $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
  10.         # Traps    
  11.         trap {if($verbose){Write-Host "General Exception"};return $false}
  12.         trap [System.Net.Sockets.SocketException]
  13.         {
  14.             if($verbose){Write-Host "Exception: $($_.exception.message)"}
  15.             return $false
  16.         }
  17.         if(!$wait)
  18.         {
  19.             $tcpclient.Close()
  20.             if($verbose){Write-Host "Connection Timeout"}
  21.             return $false
  22.         }
  23.         else
  24.         {
  25.             $tcpclient.EndConnect($iar) | out-Null
  26.             $tcpclient.Close()
  27.         }
  28.         if(!$error[0]){return $true}
  29.     }
  30.     function PingServer {
  31.         Param($MyHost)
  32.         $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
  33.         if($pingresult.statuscode -eq 0) {$true} else {$false}
  34.     }
  35. }
  36. Process{
  37.     if($_)
  38.     {
  39.         if($port)
  40.         {
  41.             if($property)
  42.             {
  43.                 if(TestPort $_.$property){$_}  
  44.             }
  45.             else
  46.             {
  47.                 if(TestPort $_){$_}
  48.             }
  49.         }
  50.         else
  51.         {
  52.             if($property)
  53.             {
  54.                 if(PingServer $_.$property){$_}  
  55.             }
  56.             else
  57.             {
  58.                 if(PingServer $_){$_}
  59.             }
  60.         }
  61.     }
  62. }

If you want this as a function use this code

  1. function Test-Host{
  2. Param($property,$tport=135,$timeout=1000,[switch]$port,[switch]$verbose)
  3. Begin{
  4.     function TestPort {
  5.         Param($srv)
  6.         $error.Clear()
  7.         $ErrorActionPreference = "SilentlyContinue"
  8.         $tcpclient = new-Object system.Net.Sockets.TcpClient
  9.         $iar = $tcpclient.BeginConnect($srv,$tport,$null,$null)
  10.         $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
  11.         # Traps    
  12.         trap {if($verbose){Write-Host "General Exception"};return $false}
  13.         trap [System.Net.Sockets.SocketException]
  14.         {
  15.             if($verbose){Write-Host "Exception: $($_.exception.message)"}
  16.             return $false
  17.         }
  18.         if(!$wait)
  19.         {
  20.             $tcpclient.Close()
  21.             if($verbose){Write-Host "Connection Timeout"}
  22.             return $false
  23.         }
  24.         else
  25.         {
  26.             $tcpclient.EndConnect($iar) | out-Null
  27.             $tcpclient.Close()
  28.         }
  29.         if(!$error[0]){return $true}
  30.     }
  31.     function PingServer {
  32.         Param($MyHost)
  33.         $pingresult = Get-WmiObject win32_pingstatus -f "address=’$MyHost’"
  34.         if($pingresult.statuscode -eq 0) {$true} else {$false}
  35.     }
  36. }
  37. Process{
  38.     if($_)
  39.     {
  40.         if($port)
  41.         {
  42.             if($property)
  43.             {
  44.                 if(TestPort $_.$property){$_}  
  45.             }
  46.             else
  47.             {
  48.                 if(TestPort $_){$_}
  49.             }
  50.         }
  51.         else
  52.         {
  53.             if($property)
  54.             {
  55.                 if(PingServer $_.$property){$_}  
  56.             }
  57.             else
  58.             {
  59.                 if(PingServer $_){$_}
  60.             }
  61.         }
  62.     }
  63. }}

Build Lab w/ Quest AD CMDLets

Earlier I wrote a post about a script that I used to build my AD Lab Build Lab (v1 w/out Quest Tools) and I mentioned I
would post a Quest version. I had some time run it (took about 6hrs.) So without further ado:

Whats it do Again?
# Creates A TestOU OU
# Creates A TestComputers OU
# Creates A TestUsers OU
# Creates A TestGroups OU
# Creates 10K OU’s Under TestOU
## Each of the 10k OUs will have 4 Child OUs
### Each OU should have 5 users Accounts and 5 Machines Accounts
# Create 500 Group Policies.
# Link 100 policies on the 10k Base OUs
# Create 2000 Users in the TestUser OU
# Create 2000 Computers in the TestComputer OU
# Create 2K Groups

Note: Added Write-Progress for OU/User Creation

  1. # Adding Required Snapins
  2. Add-PSSnapin SDMSoftware.PowerShell.GPMC -ea 0
  3. Add-PSSnapin Quest.ActiveRoles.ADManagement -ea 0
  4.  
  5. $DomainDN = (([ADSI]"").distinguishedName[0])
  6. $DomainDNS = (([ADSI]"").distinguishedName[0]) -replace "DC=","" -replace ",","."
  7. $users = @()
  8.  
  9. # A TestOU OU
  10. $BaseOU = New-QADObject -Type OrganizationalUnit -ParentContainer $DomainDN  -Name TestOU
  11.  
  12. # A TestComputers OU
  13. $TestComps = New-QADObject -Type OrganizationalUnit -ParentContainer $DomainDN -Name TestComputers
  14.  
  15. # A TestUsers OU
  16. $TestUsers = New-QADObject -Type OrganizationalUnit -ParentContainer $DomainDN -Name TestUsers
  17.  
  18. # A TestGroups OU
  19. $TestGrps = New-QADObject -Type OrganizationalUnit -ParentContainer $DomainDN -Name TestGroups
  20.  
  21. # 10K OUs Under TestOU
  22. foreach($i in 1..10000)
  23. {
  24.     $lvl1Child = New-QADObject -Type OrganizationalUnit -ParentContainer $BaseOU.dn -Name "LvL1ChildOU$i"
  25.     Write-Progress "Creating OUs LvL1ChildOU$i" -status "Updating" -perc ($i/10000*100)
  26.     ## Each of the 10k OUs will have 4 Child OUs
  27.     foreach($x in 1..4)
  28.     {
  29.         $lvl2Child = New-QADObject -Type OrganizationalUnit -ParentContainer $lvl1Child.dn -Name "LvL2Child${i}${x}"
  30.         Write-Progress "Creating Child OUs LvL2Child${i}${x}" -status "Updating" -perc ($x/4*100) -id 1  
  31.         foreach($y in 1..5)
  32.         {
  33.             ## Each OU should have 5 users Accounts and 5 Machines Accounts
  34.             Write-Progress "Creating Child Users/Computers" -status "Updating" -perc ($y/5*100) -id 2
  35.             New-QADUser -ParentContainer $lvl2Child.dn -Name "usr${i}${x}${y}" -SamAccountName "usr${i}${x}${y}" -UserPrincipalName "usr${i}${x}${y}@$DomainDNS" -UserPass "!P@ssw0rd22!" | Out-Null
  36.             New-QADObject -ParentContainer $lvl2Child.dn -name "srv${i}${x}${y}" -objectAttributes @{"sAMAccountName"="srv${i}${x}${y}`$"} -type "Computer" | out-Null
  37.         }
  38.     }
  39. }
  40.  
  41. # Create 500 Group Policies.
  42. 1..500 | %{New-SDMgpo "TestGPO$_"}
  43.  
  44. # Link 100 policies on the 10k Base OUs
  45. 1..100 | %{Add-SDMgpLink -name "TestGPO$_" -scope "OU=LvL1ChildOU$i,$($BaseOU.DN)"}
  46.  
  47. # Create 2000 Users in the TestUser OU
  48. 1..2000 | %{New-QADUser -ParentContainer $TestUsers.dn -Name "Testusr$_" -SamAccountName "Testusr$_" -UserPrincipalName "Testusr$($_)@$DomainDNS" -UserPass "!P@ssw0rd22!"}
  49.  
  50. # Create 2000 Computers in the TestComputer OU
  51. 1..2000 | %{New-QADObject -ParentContainer $TestComps.dn -name "TestComp$($_)" -objectAttributes @{"sAMAccountName"="TestComp$($_)`$"}}
  52.  
  53. # Create 2K Groups
  54. 1..2000 | %{New-QADGroup -ParentContainer $TestGrps.dn -name "TestGrp$_" -sAMAccountName "TestGrp$_"}

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 player.

Demo File

  1. #
  2. # First we need to create the MFCOM Object
  3. #
  4. $mfapp = new-object -com MetaFrameCom.MetaFrameApplication
  5. #
  6. # To initialize we need to pass the app we want to accesss
  7. #
  8. $mfapp.Initialize(3,"Applications\Powershell")
  9. #
  10. # With Applications we need to load the data
  11. #
  12. $mfapp.loaddata(1)
  13. #
  14. # Lets see what we have
  15. #
  16. $mfapp | Get-Member -type Properties
  17. #
  18. # Lets look at Users and Groups
  19. #
  20. $mfapp | select Users,Groups
  21. #
  22. # How bout Servers
  23. #
  24. $mfapp.Servers | Select ServerName
  25. #
  26. # Sessions?
  27. #
  28. $mfApp.Sessions | ft SessionID,AppName,ClientAddress,ClientHRes,ClientVRes -auto

Get-CitrixFarm (Playing Around Series)

I wanted to show how EASY it is to play with Citrix MFCom so here is a little video.

I also want to note how most of the properties (like Servers,Applications,Zones) all return objects that have their own properties and methods. So you could very easily have these lines in your profile and always have everything just sitting there waiting to be used.

  1. $farm = New-Object -Com ‘MetaframeCOM.MetaFrameFarm’
  2. $farm.Initialize(1)
  3. Write-Host "Loaded Farm Info from $($farm.FarmName)

Best Viewed Full Screen
Get the Flash Player to see this player.

Demo File

  1. # Get Citrix Farm Object
  2. #
  3. $farm = New-Object -Com ‘MetaframeCOM.MetaFrameFarm’
  4. #
  5. # Initialize Farm
  6. #
  7. $farm.Initialize(1)
  8. #
  9. # Now that we have are farm. Lets make sure we have the one we want by Getting the FarmName
  10. $Farm.FarmName
  11. #
  12. # Lets see what we have to play with
  13. #
  14. $farm | Get-Member -type Properties
  15. #
  16. #
  17. # We have the Farm we want. Some of the Info we want is Admins. So lets Start there
  18. #
  19. $farm.Admins
  20. #
  21. # To View just a list
  22. #
  23. $farm.Admins | Select FriendlyName
  24. #
  25. # Lets see what Applications we have
  26. #
  27. $farm.Applications | ft BrowserName,ParentFolderDN
  28. #
  29. # To View the Servers
  30. #
  31. $farm.Servers | ft ServerName,IPAddress,SessionCount
  32. #
  33. # How bout Sessions?
  34. $farm.Sessions
  35. #
  36. # Lets look at Print Drivers we Have installed
  37. #
  38. $farm.Drivers
  39. #
  40. # If you have multiple Zones you can get the Names Servers and DataCollector for the Zone
  41. $farm.Zones
  42. #

Get-CitrixServer (Playing Around Series)

This is a quick run through a MFCOm Citrix Server Object

Best Viewed Full Screen
Get the Flash Player to see this player.

Demo File

  1. #
  2. # We start by creating a Server Object
  3. #
  4. $mfsrv = New-Object -ComObject MetaFrameCOM.MetaFrameServer
  5. #
  6. # Initializing Server
  7. #
  8. $mfsrv.Initialize(6,$ENV:ComputerName)
  9. #
  10. # Now we have are server… Lets see what we have to play with
  11. #
  12. $mfsrv | Get-Member -type Properties
  13. #
  14. # Lets start by looking at the current sessions on the server
  15. #
  16. $mfsrv.Sessions | ft SessionID,AppName,ClientAddress,ClientHRes,ClientVRes -auto
  17. #
  18. # What about what Zone it is in?
  19. #
  20. $mfsrv.ZoneName
  21. #
  22. # Printers?
  23. #
  24. $mfsrv.Printers
  25. #
  26. # Lets see what Processes are running
  27. #
  28. $mfsrv.Processes | ft SessionID,ProcessID,UserName,ProcessState -auto
  29. #
  30. # A common task is Server Load
  31. #
  32. $mfsrv.WinServerObject.ServerLoad
  33. #
  34. # Last (and perhaps most important) What applications?
  35. #
  36. $mfsrv.Applications | ft BrowserName,ParentFolderDN

Vmotion with VI ToolKit (Playing Around Series)

I wanted to show you how simple it was to VMotion with new CMDLets. I also want to point out the most if not all the VMware CMDLets return VM Objects so you could easily do something like
Get-VM MyVM | Stop-VM | Remove-CDDrive | Move-VM -Dest $EsxHost | New-CDDrive -isoPath $isoPath -StartConnected | Start-VM

Best Viewed Full Screen
Get the Flash Player to see this player.

Demo File

  1. # Connect to Virtual Center
  2. Get-VC home.halr9000.com
  3. # Get ESX host
  4. $esxHost = Get-VMHost 192.168.0.55
  5. # Verify we got the correct ESX Host
  6. $esxHost
  7. # Get Virtual Machine
  8. $vm = Get-VM SDK-XPSP2
  9. # Verify We have the correct VM
  10. $vm
  11. # Test VM move with -whatif
  12. Move-VM -VM $VM -Destination $EsxHost -whatif
  13. # Lets do it for real
  14. Move-VM -VM $VM -Destination $EsxHost

Controlling VMWare VMs with VI Toolkit (Playing Around Series)

In this video I show starting, Pausing, Resuming and Stopping VMs using Get-VM, Start-VM, Suspend-VM, and Stop-VM

Note: These are fast run throughts, but you can pause and read the comments.

BEST VIEWED FULL SCREEN
Get the Flash Player to see this player.

Demo File

  1. # Connect to Virtual Center
  2. Get-VC home.halr9000.com
  3. # View our current VMs
  4. Get-VM
  5. # Pick Specific VM
  6. get-vm SDK-XPSP2
  7. # To start VM
  8. get-vm SDK-XPSP2 | Start-VM
  9. # To pause VM
  10. get-vm SDK-XPSP2 | Suspend-VM -Confirm:$False
  11. # To resume it again
  12. get-vm SDK-XPSP2 | Start-VM
  13. # To stop VM
  14. get-vm SDK-XPSP2 | Stop-VM -Confirm:$False

Intro to VMWare VI Toolkit for Windows (Playing Around Series)

I know there are a good bit of people out there that are unable install and play with the new VMWare toolkit. So in this post I though I would record some of my playing around with Get-VM :)

I show Get-VM, Get-HardDisks, Get-CDDrive, Get-NetworkAdapter, and Get-FloppyDrive. I recommend pausing and reading the video as you go.

Note: This is a fast run through. I recommend pausing and reading the Comments.

BEST VIEWED FULL SCREEN
Get the Flash Player to see this player.

Some shout outs:
To Hal from PowerScripting.Net for use of his Lab for recordings. Here is his blog: Hals Blog
To Camtasia for incredible product:
Click Here
To VMWare for some Great CMDLets: Click Here

Demo File

  1. Get-VC home.halr9000.com
  2. # Lets look at the all the commands we have.
  3. Get-Vicommand | more
  4. # Now lets look at Get-VM
  5. Get-VM
  6. # What properties do we have for the VMs
  7. Get-VM | Get-Member -type property
  8. # Lets look at the Hard Disks
  9. Get-VM | Get-HardDisk
  10. # Here are the properties for a HardDisk
  11. Get-VM | Get-HardDisk | Get-Member -type Property
  12. # Lets look at VMs with over 2gb of disk
  13. Get-VM | Get-HardDisk | ?{$_.CapacityKB*1kb -gt 2gb}
  14. # What about 4gb
  15. Get-VM | Get-HardDisk | ?{$_.CapacityKB*1kb -gt 4gb}
  16. # Now lets look at the CD Drives
  17. Get-VM | Get-CDDrive
  18. # What about the properties available
  19. Get-VM | Get-CDDrive | get-member -type property
  20. # Lets make sure none of the CD’s have ISO’s attached
  21. Get-VM | Get-CDDrive | ?{$_.ISOPath}
  22. # How bout NICs
  23. Get-VM | Get-NetworkAdapter
  24. # what do they have to offer?
  25. Get-VM | Get-NetworkAdapter | get-member -type property
  26. # Lets look at all the NICs, but only the Mac and NetworkName
  27. Get-VM | Get-NetworkAdapter | select MacAddress,NetworkName
  28. # Finally, Lets take a quick peak at floppies
  29. Get-VM | Get-FloppyDrive

Fun with Active Directory (Playing Around Series)

This is the first in a series of posts call “Playing Around Series.” This series will basically be demo Videos of different Snapins/.NET Classes and their use.

In this entry I run through creating a DirectoryEntry, DirectorySearcher, and using the System.DirectoryServices.ActiveDirectory.Domain Class.

Note: This is a fast run through. I STRONGLY recommend pausing and reading the Comments. Best Viewed Full Screen

Get the Flash Player to see this player.

Special Shout-out to JayKul and Jeffrey Snover for the Start-Demo script.
http://www.powershellcentral.com/scripts/302

Demo Text

  1. #
  2. # Lets start off by looking at DirectoryEntry
  3. #
  4. $DE = New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=tstUsr101,OU=MyUsers,DC=corp,DC=lab")
  5. #
  6. # First lets see what we have access to
  7. #
  8. $DE | Get-Member
  9. #’
  10. # Hmmm.. doesn’t seem like much. OH WAIT! Remember Powershell abstracts the class… Lets add psbase
  11. #
  12. $DE.psbase | Get-Member
  13. #
  14. # Lets look at what properties are available.
  15. #
  16. $DE.psbase.Properties
  17. #
  18. # Thats more like it. You may also note that some AD properties are still missing.
  19. # That is because that LDAP doesnt return all the properties. For these you need to "GET" them.
  20. $DE.psbase.InvokeGet(‘msExchUMFaxID’)
  21. #
  22. # Using DirectoryEntry is fine if you know the DN of the object, but what if you need to search?
  23. # Lets look at System.DirectoryServices.DirectorySearcher
  24. #
  25. # The Searcher needs some info so put that in variables first
  26. #
  27. $root = [ADSI]""  ## This is using the Type Accelerator we spoke about earlier… This is Gets the base
  28. $filter = "(&(objectcategory=user))"
  29. #
  30. # Now Lets create the searcher
  31. #
  32. $searcher = New-Object System.DirectoryServices.DirectorySearcher($root,$filter)
  33. #
  34. # That gets the searcher ready, but to execute we need to call findall() or findone()
  35. #
  36. $users = $searcher.findAll()
  37. #
  38. # Lets see what we got. We have alot so lets only pick the first 10
  39. #
  40. $users | select -first 10
  41. #
  42. # Tons of info, but notice that this is NOT the same as DirectoryEntry
  43. #
  44. $users | get-Member
  45. #
  46. # It still has the properties property, Lets look (but only the first 3)
  47. #
  48. $users | select -first 3 | %{$_.Properties}
  49. #
  50. # Finally Lets look at System.DirectoryDervices.ActiveDirectory.Domain
  51. #
  52. # We can use this to interactively browse around
  53. #
  54. [system.directoryservices.activedirectory.domain]::GetCurrentDomain()
  55. #
  56. # Lets assign that to variable to play with
  57. #
  58. $domain = [system.directoryservices.activedirectory.domain]::GetCurrentDomain()
  59. $domain
  60. #
  61. # Lets see what this has to offer
  62. #
  63. $domain | get-member
  64. #
  65. # Tons of cool stuff here.
  66. #
  67. # We can find all domain controllers
  68. $domain.FindAllDomainControllers()
  69. #
  70. # We Can look at our Domain FSMO
  71. #
  72. $domain | ft PdcRoleOwner,RidRoleOwner,InfrastructureRoleOwner
  73. #
  74. # I can even step the tree and get my forest root
  75. #
  76. $forest = $domain.Forest
  77. $forest
  78. #
  79. # With our new found $forest object… what can do we do?
  80. #
  81. $forest | Get-Member
  82. #
  83. # WE can find all our GCs
  84. #
  85. $forest.FindAllGlobalCatalogs()
  86. #
  87. # We can look at the Forest Mode
  88. #
  89. $forest.ForestMode
  90. #
  91. # Look at the Forest FSMO
  92. #
  93. $forest | ft SchemaRoleOwner,NamingRoleOwner
  94. #
  95. # Even look at sites
  96. $forest.Sites
  97. #
  98. # We can go on forever and ever. If you would like we can revisit this later.
  99. #

Next »