Wednesday, January 11, 2012

Using Rich HTML with Send-MailMessage

By:Rik Hoffelder
The Send-MailMessage CMDLET can be a useful tool in many ways. However it has some limitations that can be easily overcome with a little PowerShell scripting and HTML tags. I was recently asked by a customer for some ideas to help automate a notification message when a new employee joins the company. This was to be a part of a larger auto-user provisioning script that would send a welcome message to the new employee with various company information and helpful links. This particular task was performed manually by an administrator using a custom template in Outlook (.OFT file). Our mission was to convert the OFT and manual process into something we could do with Send-MailMessage.

Before I go too much further into the solution I want to thank and credit my customer, Paul Savage of McCarthy Building Companies, for pulling this all together and sharing his code with us. Thank you Paul!

First it is important to understand that Send-MailMessage allows you to use HTML in the message body using the –HtmlAsBody switch. Next we take advantage of the Get-Content and Out-String cmdlets to build the Body parameter of the message. This allows us to create a txt file with HTML tags that contain the message content and provide the same formatting that was used in the body of the OFT. So with the assistance of Paul's Sharepoint Developer we were able to create the message body text file as shown below:

Body.Txt

<style>

.colorchange {

    color:#4F81BD;

}

</style>

<html xmlns="http://www.w3.org/1999/xhtml">

<body>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">Welcome to Company Name Here!&nbsp; We are glad you are here!&nbsp;&nbsp; Below are some helpful items to get you started.</p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">Our company provides a library of documents to help you with your daily tasks and responsibilities <a href="http://intranet.company.com/employee%20%documents ">by clicking here.</a>.</p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">The <a href=" http://intranet.company.com/hr">Human Resources Policies Manual</a> should be thoroughly reviewed.&nbsp; By replying, you are acknowledging receipt and consent to the Policies outlined in the Manual.</p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">In addition to policies noted above, please take a moment to review and understand a few additional guidelines when using our Information Systems.&nbsp; They are: </p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">&nbsp;1.&nbsp; Use of the Mass Distribution Function Company E-Mail System- <a href="http://intranet.company.com/hr/Mass+Email+Distribution.doc">http:// intranet.company.com/hr/Mass+Email+Distribution.doc</a><br />

&nbsp;2.&nbsp; Spam E-Mails- <a href="http:// intranet.company.com/hr/Email-SPAM-Filtering-Service.aspx">http:// intranet.company.com/hr/Email-SPAM-Filtering-Service.aspx</a> <br />

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">Again, the intent of these policies and procedures are to provide for necessary safeguards that protect all employees interests and our company.&nbsp;&nbsp; If you have any questions on the policies or procedures, feel free to contact the I.T. Help Desk at 800-555-1234.&nbsp; They will forward your questions to the appropriate personnel who can assist you.</p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt">Thank you and welcome aboard!</p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:10pt"><b>Jane Doe</b> | <span class="colorchange">Director</span></p>

<p style="font-family:Tahoma, Geneva, sans-serif; font-size:8pt; color:#808080">Human Resources | Company Name, Inc.<br/>(800) 555-1234</p>

</body>

</html>

Next we reference the body file in the script as shown below:

SendWelcomeEmail.PS1

$messageParameters = @{

Subject = "Welcome Aboard!"

Body = Get-Content "C:\body.txt" | out-string

From = "Welcome@company.com"

To = "NewEmployee@company.com"

SmtpServer = "smtp.company.com"

}

Send-MailMessage @messageParameters –BodyAsHtml

With a little bit of tweaking you can easily pass a variable to the script by adding the following:

SendWelcomeEmail.PS1 NewEmp

(Example .\SendWelcomeEmail.PS1 john.doe@company.com)

Param(

    [string] $NewEmp = ""

)

function ValidateParams

{

$validInputs = $true

$errorString = ""

if ($NewEmp -eq "")

{

    $validInputs = $false

    $errorString += "`missing parameter: The employee email address parameter is required. Please enter a valid email address. Example: john.doe@company.com"

}

if (!$validInputs)

{

    Write-error "$errorString"

}

return $validInputs

}

### Validate the parameters ###

$ifValidParams = ValidateParams;

if (!$ifValidParams) { exit; }

$messageParameters = @{

Subject = "Welcome to the Company!"

Body = Get-Content "C:\body.txt" | out-string

From = "Welcome@company.com"

To = &NewEmp

SmtpServer = "smtp.company.com"

}

Send-MailMessage @messageParameters –BodyAsHtml


 

Good luck and happy scripting!




More information on PowerShell

Read more!

Wednesday, October 26, 2011

Barcelona Citrix Synergy Keynotes

By:Rick Rohne

Today’s keynotes @Citrix Synergy remind me why I got into the Technical Industry in the first place. It’s not about knowing how things work or how to make things work. It’s all about understanding market trends and business trends and understanding how that fits into today’s business and of course my professional life. Here are some key Topics to todays Keynotes

  • Citrix Acquires App-DNA – Mark T didn’t go too far into how they plan to market or sell the product. IMHO, App-DNA has so much Intellectual Property and this is a great move which allows Citrix to help organizations perform Desktop transformations faster and more efficient.

  • Citrix Acquires ShareFile – ShareFile allows Data to Integrate into “ALL” Citrix products so finally - the Term and Strategy of Follow-Me Data is now revealed. Sharefile is an Enterprise Cloud Storage platform with many Enterprise Features such as a robust Outlook Plugin that allows a user to send a link to files automatically based on User or Admin Driven Policy. Sync with all devices everywhere, Sync with Receiver Plugins, Online and Offline Data, Remote Wipe of Data (See all devices that you have logged into and remote wipe). I would like to see Citrix integrate this into Policy Driven Enterprise Storage with Storage API’s and maybe Integration into a Personal vDisk.

  • Speaking of Personal vDisks - Ringcube Strategy Revealed - Personal vDisks gives a place for users to store Data, Install Apps, Personality, etc. My 2 Cents… Integrate with other Management products like SCCM or provide a space for App-V or XENAPP Streamed apps cached space to be persistent. Use AppSense or other 3rd party products to authorize the installation of 1 off apps or Plugins that system administrators can’t or have not published. I’m not a fan of giving users admin rights, so I’ll talk about this a little later…

  • GoToMeeting Workspaces – Collaborate with Documents online with HD-Faces and GoToMeeting all in one virtual room. GTM Workspaces integrates with ShareFile Cloud Storage. Mark up documents and collaborate as if you were in the same room.

  • Citrix Cloud Gateway Express – Used with XENAPP and XENDesktop. IMHO - Basically Access Gateway Integration with StoreFront.

  • Citrix Cloud Gateway Enterprise – Combine Citrix XENAPP, XENDESKTOP with Follow-Me Data and Follow-Me SaaS Apps. IMHO -> I envision this being similar to the Universal Licenses or maybe even a replacement. This seems to be the NEW BIG 3 that Citrix will be offering.

  • Web Interface is dead in 2015. Welcome the new StoreFront! StoreFront brings Follow-Me Apps, Desktops, Follow-Me Data, and SaaS apps delivered from a unified platform (Citrix Receiver). More info to come on this, although it is a radical step, I believe it to be the right direction to drive the adoption of Follow-Me theme.

  • HDX System on a Chip – Texas Instruments creates the first HDX enabled Chip that allows for updates to keep up with HDX technologies. The plan is to drive the cost of a thin client down below $100. Enable Desktop Transformation to move faster. NComputing making first devices. Demo of Metro Receiver for Windows 8 – Great Metro Feel of Receiver apps, Allows Citrix to use Virtual Desktops as a True Touch Screen Desktop.

  • Netscaler Cloud Connectors – API’s to drive single management of Private and Public Clouds from a single interface.

  • Cloud Stack and Cloud Portal Announced today. Great customizable platform for the Clouds (supports all Hypervisors).

  • Receiver for Facebook – This was the last announcement. More of an attention getter than a major innovation, and I believe they got some heads to turn. Basically Receiver for Facebook allows you to connect to your Apps and Data using HTML 5 embedded into the Facebook application.
Be sure to follow me @RicksLife the rest of this week. Lots of good content! Man! Feels good to be back!

Read more!

Monday, July 18, 2011

RightFax Integration Module in a Collective

By:Rik Hoffelder


The RightFax Shared Services Collective is a wonderful feature that allows load balance and failover in a shared nothing architecture. There is an exception to this however the Integration Module cannot run on multiple nodes when sharing the same Inbox. When this is done you end up with duplication of faxes.

As shown below a typical environment will use two or more collective servers with the IM. It reads from Inboxes on a clustered file share with all application servers feeding to this location. This makes for a great high availability solution, but doesn't solve the IM problem.



To workaround this problem most administrators disable the IM service on all but one collective server. In the event of a primary server failure they manually start the service on another collective member. This is an acceptable workaround however it has two flaws. The first is that it’s a manual process. The second issue occurs when the original server is recovered. You have to remember to shutdown the IM service on the other server.

As a field consultant I have encountered this situation on numerous occasions. In a few cases the project required that I provide some mechanism to fail this over automatically. There are a few ways to accomplish this outside of RightFax depending on what you have available. So for those of you that have struggled with this situation here’s how I accomplished it using a VB Script. I also have lightly tested PowerShell version. Note that neither script is sanctioned or supported by OpenText.

The script, RFMonitor.VBS, uses a CSV input file named RFMonitor.INI. This file provides the services and servers used as input varibles for the script. The fields are RF Service Monitored, Primary Server, Secondary Server. I run the script as a scheduled task on a separate server (management server) every 10 minutes.

It essentially pings the primary to make sure it’s up, if not it fails over to the secondary immediately. If the primary is up it verifies the services are running, if not it fails over. It also checks to see if the IM service is running on both servers. If so, it stops it on the secondary. This has been tested extensively and is running in a couple of production environments.

RFMonitor.INI

RFPROD,FAXSRV02,FAXSRV01,
RFSERVER,FAXSRV02,FAXSRV01,
RFDOCTRANS,FAXSRV02,FAXSRV01,
RFPAGE,FAXSRV02,FAXSRV01,
RFQUEUE,FAXSRV02,FAXSRV01,
RFREMOTE,FAXSRV02,FAXSRV01,
RFRPC,FAXSRV02,FAXSRV01,
RFIsoConv,FAXSRV02,FAXSRV01,
CapaSync,FAXSRV02,FAXSRV01,
RFEMAIL,FAXSRV02,FAXSRV01,
RFMIME,FAXSRV02,FAXSRV01,
RFWORK1,FAXSRV02,FAXSRV01,
RFWORK2,FAXSRV02,FAXSRV01,
RFWORK3,FAXSRV02,FAXSRV01,


RFMonitor.VBS

On Error Resume Next
'##### Open and parse CSV for varibles #####
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("rfmonitor.ini", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
arrFields = Split(strLine, Chr(44))
strSvc = arrFields(0)
strMainSrv = arrFields(1)
strBkupSrv = arrFields(2)
Call CheckMainSrv()
Loop
'##### Check Main Server Availability #####
Sub CheckMainSrv()
strComputer = "."
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec("ping " & strMainSrv)
Set objStdOut = objWshScriptExec.StdOut

While Not objStdOut.AtEndOfStream
strLine = objStdOut.ReadLine
If InStr(strLine,"Reply from") Then
Call CheckBkupSrv()
Else
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 1, strMainSrv & " " & "is unreachable, starting services on" & " " & strBkupSrv
Call StartBkupSrv()
End If
Wend
End Sub

'##### Check Backup Server Availability #####
Sub CheckBkupSrv()

strComputer = "."
Set objShell = CreateObject("WScript.Shell")
Set objWshScriptExec = objShell.Exec("ping " & strBkupSrv)
Set objStdOut = objWshScriptExec.StdOut

While Not objStdOut.AtEndOfStream
strLine = objStdOut.ReadLine
If InStr(strLine,"Reply from") Then
Call CheckSvcType()
Else
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 1, strMainSrv & " " & "is unreachable, checking services on" & " " & strMainSrv
Call StartMainSrv()
End If
Wend

End Sub

'##### Check Service Type #####
Sub CheckSvcType()

If strSvc = "RFPROD" Then
Call CheckIMSvc()
ElseIf strSvc = "RIGHTFAXONFAX011024" Then
Call CheckGPSvc()
ElseIf strSvc = strSvc Then
Call CheckSvcState()
End If
End Sub

'##### Check State of Services Fail As Needed #####
Sub CheckSvcState()

strQ1 = "Select * from Win32_Service"
strQ2 = "Where Name = '" & strSvc & "'"
strQuery = strQ1 & " " & strQ2

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery(strQuery)
For Each objService in colListOfServices
If ObjService.State = "Stopped" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 1, objService.DisplayName & " " & "service has stopped on" & " " & strMainSrv
Call SvcFail()
Else
End If
Next

End Sub
'##### Check Integration Module service state #####
Sub CheckIMSvc()
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='RFPROD'")
For Each objService in colListOfServices
If ObjService.State = "Stopped" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 1, objService.DisplayName & " " & "service has stopped on" & " " & strMainSrv
Call StartRFProdSvc()
Else
Call CheckDupIMSvc()
End If
Next
End Sub
'##### Check Get PAID service state #####
Sub CheckGPSvc()
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='RIGHTFAXONFAX011024'")
For Each objService in colListOfServices
If ObjService.State = "Stopped" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 1, objService.DisplayName & " " & "service has stopped on" & " " & strMainSrv
Call StartGPSvc()
Else
Call CheckDupGPSvc()
End If
Next
End Sub
'##### Start RFPROD Service Routine #####
Sub StartRFProdSvc()
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")
Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RFPROD'")
For Each objService in colServiceList
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strBkupSrv & " " & "Failover Completed!"
Next
End Sub
'##### Start GetPaid Service Routine
Sub StartGPSvc()

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RIGHTFAXONFAX011024'")

For Each objService in colServiceList
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strBkupSrv & " " & "Failover Completed!"
Next
End Sub

'##### Check RFPROD Serivce on second node, stop if running #####
Sub CheckDupIMSvc()

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RFPROD'")

For Each objService in colServiceList
If ObjService.State = "Running" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 2, objService.DisplayName & " " & "Service is running on" & " " & strBkupSrv & " " & "stopping service to prevent duplicates!"

errReturn = objService.StopService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been stopped on" & " " & strBkupSrv
Else
End If
Next
End Sub

'##### Check RFPROD Serivce on second node, stop if running #####
Sub CheckDupGPSvc()

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RIGHTFAXONFAX011024'")

For Each objService in colServiceList
If ObjService.State = "Running" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 2, objService.DisplayName & " " & "Service is running on" & " " & strBkupSrv & " " & "stopping service to prevent duplicates!"

errReturn = objService.StopService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been stopped on" & " " & strBkupSrv
Else
End If
Next
End Sub

'##### Other Service Failure #####
Sub SvcFail()

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RFPROD'")

For Each objService in colServiceList
If ObjService.State = "Running" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 2, objService.DisplayName & " " & "Service is running on" & " " & strMainSrv & " " & "stopping service to failover!"

errReturn = objService.StopService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been stopped on" & " " & strMainSrv
Else
End If
Next

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RIGHTFAXONFAX011024'")

For Each objService in colServiceList
If ObjService.State = "Running" Then
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 2, objService.DisplayName & " " & "Service is running on" & " " & strMainSrv & " " & "stopping service to failover!"

errReturn = objService.StopService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been stopped on" & " " & strMainSrv
Else
End If
Next
Call StartRFProdSvc()
Call StartGPSvc()
End Sub


'##### Main Server Fail, Start Backup Server #####
Sub StartBkupSrv()

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RFPROD'")

For Each objService in colServiceList
If objService.State = "Stopped" Then
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strBkupSrv
Else
End If
Next

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strBkupSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RIGHTFAXONFAX011024'")

For Each objService in colServiceList
If objService.State = "Stopped" Then
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strBkupSrv
Else
End If
Next
End Sub


'##### Backup Server Fail, Start Main Server #####
Sub StartMainSrv()
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RFPROD'")

For Each objService in colServiceList
If objService.State = "Stopped" Then
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strMainSrv
Else
End If
Next

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strMainSrv & "\root\cimv2")

Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='RIGHTFAXONFAX011024'")

For Each objService in colServiceList
If objService.State = "Stopped" Then
errReturn = objService.StartService()
Set LogError = Wscript.CreateObject("Wscript.Shell")
LogError.LogEvent 0, objService.DisplayName & " " & "service has been started on" & " " & strMainSrv
Else
End If
Next
End Sub


RFMonitor.PS1 (PowerShell Version)

Like I noted earlier, this has barely been tested and never used in a production environment. If you have something better or cleaner, please feel free to share. This was one of the first PS scripts I wrote over 6 years ago, so I’m sure it could use some improvements.


#Script Notes: Ping server, if alive Check service state on main from ini file, start on bkup if stopped,
#checks for RFPROD and GetPaid specificially.

####Check Main and Backup for duplicate RFAXONFAX011024 running, stop on Backup
Function CheckGPDup {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFAXONFAX011024'"
$State = $colitem.state
if ("$State" -eq "running")
{write-host "Stopping RFPROD service on Backup server to prevent duplicate faxes."
$colItem1 = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFAXONFAX011024'"
ForEach ($objItem in $colItem1) {$objItem.StopService()}}
else
{write-host "No duplicate RFAXONFAX011024 service running on" $Bkup"."}
}


####Check Main and Backup for duplicate RFPROD running, Stop on Backup
Function CheckRFProdDup {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFPROD'"
$State = $colitem.state
if ("$State" -eq "running")
{write-host "Stopping RFPROD service on Backup server to prevent duplicate faxes."
$colItem1 = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFPROD'"
ForEach ($objItem in $colItem1) {$objItem.StopService()}}
else
{write-host "No duplicate RFPROD service running on" $Bkup"."
ChkGPDup}
}


####Failover (Stop on main, start on Backup) for any failed service
Function FailOverRFProdGP {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Main" –filter "Name= 'RFPROD'"
ForEach ($objItem in $colItem) {$objItem.StopService()}

$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Main" –filter "Name= 'RFAXONFAX011024'"
ForEach ($objItem in $colItem) {$objItem.StopService()}

$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFPROD'"
ForEach ($objItem in $colItem) {$objItem.StartService()}

$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFAXONFAX011024'"
ForEach ($objItem in $colItem) {$objItem.StartService()}

write-host "RFPROD and RFAXONFAX011024 has been started on" $bkup"."}


####Check all other services, per ini
Function CheckSvcs {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Main" –filter "Name= '$Name'"
$State = $colitem.state
if ("$State" -eq "stopped")
{write-host "Failing over IM and GP to" $Bkup"."
FailOverRFProdGP}
else
{write-host "Service" $Name "is already running on" $Main"."
CheckRFProdDup}
}


####Start RFAXONFAX011024 on Backup
Function StartGPBkup {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFAXONFAX011024'"
ForEach ($objItem in $colItem) {
$objItem.StartService()}
write-host "RFAXONFAX011024 has been started on" $bkup"."}

####Start RFPROD on Backup
Function StartRFProdBkup {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Bkup" –filter "Name= 'RFPROD'"
ForEach ($objItem in $colItem) {
$objItem.StartService()}
write-host "RFPROD has been started on" $bkup"."}

####Check RFAXONFAX011024
Function CheckGP {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Main" –filter "Name= 'RFAXONFAX011024'"
$State = $colitem.state
if ("$State" -eq "stopped")
{write-host "Starting RFAXONFAX011024 service on Backup server."
StartGPBkup}
else
{write-host "Service RFAXONFAX011024 is already running on" $Main"."
CheckSvcs}
}

###Check RFPROD
Function CheckRFProd {$colItem = get-wmiobject -class "Win32_Service" -namespace "root\cimv2" -computername "$Main" –filter "Name= 'RFPROD'"
$State = $colitem.state
if ("$State" -eq "stopped")
{write-host "Starting RFPROD service on Backup server."
StartRFProdBkup}
else
{write-host "Service RFPROD is already running on" $Main"."
CheckGP}
}

#### Open file and pasre varibles ####
$INIFILE = Import-CSV -path "C:\Documents and Settings\rhoffelder\desktop\rfmonitor.ini"

ForEach ($objItem in $INIFILE) {
$Name = $objItem.Name
$Main = $objItem.Main
$Bkup = $objItem.Bkup

#### Ping Main Srver ####
$ping = new-object System.Net.NetworkInformation.Ping
$status = $ping.send($Main)
write-host $status
if($status) {CheckRFProd}

#### Ping Backup Server ####
else {$ping = new-object System.Net.NetworkInformation.Ping
$status = $ping.send($Bkup)
write-host $status
if($status) {FailOverRFProdGP}
Else {"Both servers offline!"}}}
write-host "finished!"





More information on RightFax




Read more!

Monday, June 27, 2011

Technical Deep Dive: XenApp Load Evaluators

By: Andy Paul

One of the often overlooked features of XenApp is truly understanding the load evaluators. As a consultant, I commonly see environments using only the Default Load Evaluator. If I am lucky, they might be using the Advanced Load Evaluator. Rarely do I find organizations actively monitoring or customizing their load evaluators.

Load Evaluators have not changed much since Presentation Server days, but amazingly they are not commonly optimized. Every environment and every workload is different, so whichever load evaluator is implemented may vary, but they should be customized and monitored.

Here is a screen shot of the XenApp 6 Advanced Load Evaluator, which is now the default assignment. It creates a load based on CPU Utilization, Load Throttling, Memory Usage and Page Swaps. The Default Load Evaluator (assigned by default in XenApp 5 and prior versions) measures Server User Load.

I generally recommend creating a custom load evaluator based on resources, usually CPU Utilization, Load Throttling, Memory Usage and possibly Server User Load. This way, I can spread the load across servers based on number of users, resource loads and help prevent login storms.

Understanding Loads
But assigning a Load Evaluator is only part of the battle. You must also understand what and how that load is calculated. A simple QFARM /LOAD will show you server loads (or QFARM /LTLOAD to see the server resource load without calculating Load Throttling.) However, if you are using a load evaluator with multiple components, what is causing the load? The base algorithm for establishing actual load is Highest_Load + (Average_Other_Loads * .1).

Assuming you have a load evaluator monitoring CPU Utilization, Memory Usage and Load Throttling, and you see a server with a 7800 load value, it may be dangerously close to 10000 (Full Load) since that 7800 is not the aggregate of all loads, but reflective of the highest load, which could be close to reporting full. In this case, perhaps that server is running at 78% Memory Usage, with a cap set to 80% in the load evaluator… one more process may send it over the edge.

Detailed Load Monitoring
So what can you do about it? Knowing your environment is key, as is monitoring actual loads and adjusting evaluators or adding capacity as necessary. To this end, you can run real-time analysis of the various components of a load evaluator using the QUERYDS tool from Citrix. Additional information is available under CTX112082. These were originally published for Presentation Server 4.0, but are still valid for all editions, including XenApp 6. Please note, the output from QUERYDS will be hex values, and will need to be converted. Most applications include a Hex-Decimal conversion function, or you can use a free online converter such as http://easycalculation.com/hex-converter.php

The following table identifies the code values of the different load evaluator properties:
a -- Application User Load
2 -- Context Switches
1 -- CPU Utilization
7 -- Disk Data l/O
8 -- Disk Operations
9 -- IP Range
d -- Load Throttling
3 -- Memory Usage
4 -- Page Faults
6 -- Page Swaps
5 -- Scheduling
b -- Server User Load

Using this information, take the sample below; consisting of three servers:

Server TEST02 has a load of 1610 (HEX 64a). This load is comprised of:
  • Server User Load: 2 (b:2)
  • Load Throttling: 0 (d:0)
  • Memory Usage: 16 (3:10)
  • CPU Utilization: 0 (1:0)
These are percentages of 100, so a Memory Usage load of 16 is a load value of 1600. Load Throttling is not calculated since there is no current logon event. That leaves the average of Server User Load and CPU Utilization (200+0)/2*.1 = 10. This makes the total load value of 1610.

Conclusion
Now that you have a way to view the load components (QUERYDS) and an understanding on how to interpret the results, these values can be read and automated into a monitoring solution - either real-time or historical. Once a baseline is established, alerts can be generated as values approach full loads. Based on this information, you can then decide if you should modify your evaluators or add capacity.


Additional Reading:

Read more!

Monday, March 7, 2011

XenDesktop 5 Deep Dive: Machine Creation Services on vSphere 4.1

By: Andy Paul

When XenDesktop Desktop Studio is configured, a hosting infrastructure and storage system is defined. This hosting infrastructure can be Citrix XenSerspver, VMWare ESX/vSphere, or Microsoft Hyper-V. Storage for use by XenDesktop is also defined, which can be local storage or shared storage. In a production vSphere environment, shared storage defined as VMWare Datastores is preferred.

When using Machine Creation Services (MCS) in XenDesktop 5 Desktop Studio, a Master Image is identified when a Catalog is created. MCS Catalogs can be designed for Dedicated or Pooled virtual desktops. Pooled Assignments can be set for static assignment or random access.

Dedicated Catalog virtual desktops retain all changes, including software installations and local data, in a local difference disk. Pooled Catalog virtual desktops do not retain changes, the difference disk is reset upon reboot, leaving only a copy of the master image. However, when using pooled desktops, the base image can be updated allowing changes from the master disk to be replicated to the deployed VMs, providing for centralized patch and application management. Each deployed image, whether pooled or dedicated, will also contain an identity disk; all deployments utilize thin provisioning.

The following chart highlights the benefits of each type of XenDesktop Catalog:

Graphic taken from CTX127587: XenDesktop 5 - Reference Architecture

During this test implementation, two Dedicated Catalogs are used to pilot XenDesktop 5. One catalog will be based on Windows XP, the other catalog will be based on Windows 7. These catalogs and the dedicated machines will be assigned to Desktop Groups for different business units.

Master Image Utilization
Once a master image is identified as part of the Catalog creation, a private-use clone of the VMDK is created for use by the catalog machines. This cloned disk is separate from the Master Image VM, allowing that VM to be updated or deleted with no impact on the MCS deployed virtual desktops.

This master image clone is copied to each Datastore defined during XenDesktop site setup. This site definition can be modified to include additional storage as it becomes available. If five datastores are defined the clone will be created on the first Datastore and then copied to the remaining four.

Each catalog is linked to its own master image clone. If multiple catalogs are defined, then multiple master clones will be generated. Any additional machines created within a catalog will use the defined master image. A master image can be changed to a different disk using the following command in PowerShell: Publish-ProvMasterVmImage (click here for an example of using this command if necessary.) This change would only impact new machines created in the catalog, not existing machines already generated.

Impact on Storage
Since MCS uses thin-provisioning, using Pooled or Dedicated desktops should require less storage than existing VM creations. On vSphere, the MCS service creates a snapshot for each VM called “Do Not Delete – Critical.” This snapshot is a reversion point back to initial deployment. For Dedicated desktops, additional snapshots can be created using vCenter’s Snapshot Manager functionality.

The master image, stored on each Datastore, becomes a private-use read-only VMDK for each MCS created VM. Depending on the NAS/SAN functionality, this image may be deduplicated or moved to high-utilization storage due to the increased read ratios.

For Pooled machines, the snapshot growth will be limited since it is reset at each reboot. Dedicated machine snapshots will grow over time as changes to the virtual desktop occur. It is recommended to incorporate profile management and data redirection where possible in either scenario to increase user flexibility and reduce data changes inside the images.

Determining Storage Requirements
Since MCS uses thin-provisioning, only the amount of space required is actually used, allowing for a potential of over-allocation of storage. When analyzing storage utilization, the key item to examine is the snapshot space utilized by each VM. Since the master image is shared, this is a “fixed” cost, where snapshot growth will be dynamic.

Please note, a snapshot can grow as large as the base disk, so if the master image is 40 GB in size, the associated snapshot for a dedicated machine can grow up to 40 GB in size; effectively doubling storage requirements if left unmanaged.

To see snapshot space utilized in vCenter, select the Datastore in question, select the Storage Views tab. This view will show the space used for each virtual machine as well as snapshot space used. For MCS created machines, the space used is misleading, since it is also counting the base image size. In the example below, the master image is 40 GB in size. For VXPXDTest002 (highlighted), the Space Used is 46.11 GB, but the actual space used is really 6.11 GB since 40 GB is for the shared master image. Of the 6.11 GB used, 4.09 GB is snapshot space.
To see more exact detail, you can browse the Datastore, examining the folder for VXPXDTest002, as shown below. Notice the total space used which is the active snapshot plus the memory swap file. The base image is stored in its own folder:

Sizing Wizard
Along with this analysis, I have created an Excel worksheet called
MCS Sizing Wizard. This worksheet will help determine the size required for MCS deployed dedicated machines. The basic formulas are:
    Determine size requirements for master image:
    ..... [VMDK Size] * [# of Datastores]
    Determine size requirements for deployed virtual machines:
    ..... Create estimates for low, medium, and high usage snapshots
    ..... Per machine: [identity disk] + [RAM swap file] + [estimated size of snapshot]
    ..... Total VM sizing: [# of VMs] * [Per Machine Estimates]
    Determine total storage requirements
    ..... Most likely storage: [Expected VM storage] + [Master image storage]
Using the worksheet, creating 120 Windows 7 dedicated machines, spread across 5 datastores, with a 40 GB master VMDK, 4 GB RAM and an average snapshot size of 15 GB would use 2.4 TB of storage out of a maximum provision of 5.4 TB of storage. If using standard (existing) VMs, the same number of machines would use approximately 5.1 TB of space, for a net savings of 2.8 TB of utilized SAN storage. Using the worksheet, creating 120 Windows 7 dedicated machines, spread across 5 datastores, with a 40 GB master VMDK, 4 GB RAM and an average snapshot size of 15 GB would use 2.4 TB of storage out of a maximum provision of 5.4 TB of storage. If using standard (existing) VMs, the same number of machines would use approximately 5.1 TB of space, for a net savings of 2.8 TB of utilized SAN storage.

About this Article
The purpose of this article is to summarize the underlying architecture and impact of using Machine Creation Services in a pilot environment. This article is not intended to replace the XenDesktop Admin Guide or the XenDesktop PoC Implementation Guide.

The scope of this article is to help understand and manage the virtual machines created by MCS as well as understanding the storage requirements when using MCS. The actual amount of storage will grow over time as the snapshots grow and should be managed appropriately. Any sizing numbers are for illustrative purposes only and are no way intended as definitive calculations.

To help with the additional planning, design and optimization areas, it is recommended to utilize the XenDesktop Design Handbook Success Kit.

Additional References
XenDesktop 5 hosted-virtual desktop architecture series
XenDesktop 5 scalability: Site Capacity
PVS or MCS: We Are Talking About IOPS Again
PVS or MCS: Operations Is Important
Provisioning Services or Machine Creation Services: Big Picture Matters
XenDesktop 5 Virtual Machine Creation Services on vSphere 4.1

Read more!

Friday, October 8, 2010

Bulk Create Exchange 2010 Databases

By:Rik Hoffelder


Here's a handy script I wrote to bulk create mailbox databases to follow a strict naming convention and consistent configuration. It was designed to work with Exchange 2010, however it works just as well with 2007. The intent is to help organizations maintain consistency using a simple process that can be performed by less skilled administrators.


Script itself uses several command line parameters to create the variables needed for the scripts. The following provides the script usage:


.\createdbs.ps1 2010Server NumberOfDatabases DatabaseStartNumber DatabaseDrive LogDrive WarningQuota SendQuota SendReceiveQuota DeletedItemRetention MailboxRetention Oab PfDb

The following is an example of proper usage:

.\CreateDbs.PS1 EX2010 4 1 E D 450MB 500MB Unlimited 30 14 "\Default Offline Address List" "Public Folder Database 1"

In the above example 4 databases are created on server EX2010 with the following names:

EX2010-DB01-0500
EX2010-DB02-0500
EX2010-DB03-0500
EX2010-DB04-0500

The database are created on drive E, with the log files on drive D. The mailbox store is set to issue size limit warnings at 450MB, prohibit send at 500MB, and prohibit send/receive is set to unlimited. Next deleted items are retained for 30 days, while deleted mailboxes are retained for 14. Finally the Offline Address book is set along with the public folder database used by each mailbox store.

So let's suppose we need to create 3 more databases, but this time on drive G, with the logs on drive H. Let's also set the mailbox size limit to 1GB. You would run the following:

.\CreateDbs.PS1 EX2010 3 5 G H 900MB 1GB 2GB 10 7 "\North America OAB" "Public Folder Database 2"

This would have created databases EX2010-DB05-1000, EX2010-DB06-1000, and EX2010-DB07-1000 with 10 day deleted item retention, 7 day delete mailbox retention, a warning limit of 900MB, prohibit send at 1GB and prohibit send/receive at 2 GB. The OAB would be set to North America OAB and use Public Folder Database 2.

Notice how the DBxx value began with DB05 and the last four digits are now 1000.
The DbStartNum parameter determine the beginning of the numbering scheme in the DBxx portion. The -XXXX at the end uses the ProhibitSend value to represent the mailbox send size limit, making it easy for administrators to identify where to place mailboxes by the database name. A size limit of 125MB would produce a name SERVER-DBXX-0125 and so forth.

It's simple and flexible. To run it simply copy it to a PS1 file then lanuch it from Exchange Management Shell.

CreateDatabases.PS1

### BEGIN SCRIPT ###
Param(
[string] $2010Server = "",
[decimal] $NumDatabases = "",
[decimal] $DbStartNum = "",
[string] $DbDrive = "",
[string] $LogDrive = "",
[string] $WarnQuota = "",
[string] $SendQuota = "",
[string] $SendReceiveQuota = "",
[string] $DeletedItemRetention = "",
[string] $MailboxRetention = "",
[string] $OAB = "",
[string] $PfDb = ""
)

# This function validates the scripts parameters
function ValidateParams
{
$validInputs = $true
$errorString = ""
if ($2010Server -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The 2010Server parameter is required. Please enter the name of the Exchange 2010 server to configure. Example KCCEX2010"
}
if ($NumDatabases -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The NumDatabases parameter is required. Please enter the number of mailbox databases that will be created on this Exchange 2010 server. Example 8."
}
if ($DbStartNum -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The DbStartNum parameter is required. Please enter the starting database number. Example 5."
}
if ($DbDrive -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The DbDrive parameter is required. Please enter the drive letter on which you will create mailbox databases. Example: E"
}
if ($LogDrive -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The LogDrive parameter is required. Please enter the drive letter on which you will create transaction logs. Example: D"
}
if ($WarnQuota -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The WarnQuota parameter is required. Please enter the vaule to issue mailbox size limit warning. Example: 450MB or 1.5GB"
}
if ($SendQuota -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The SendQuota parameter is required. Please enter the vaule to issue mailbox size limit exceeded. Example: 500MB or 1GB"
}
if ($SendReceiveQuota -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The SendReceiveQuota parameter is required. Please enter the vaule at which the mailbox stops accepting mail. Example: Unlimited or 550MB"
}

if ($DeletedItemRetention -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The DeletedItemRetention parameter is required. Please enter the vaule in days. Example: 14"
}
if ($MailboxRetention -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The MailboxRetention parameter is required. Please enter the vaule in days. Example: 30"
}
if ($OAB -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The OAB parameter is required. Please enter the name of the offline address list to be used by this mailbox database in quotes. Example: 'Corporate OAB' "
}
if ($PfDb -eq "")
{
$validInputs = $false
$errorString += "`nMissing parameter: The PfDb parameter is required. Please enter the name of the public folder database in quotes. Example: 'Pub Folders DB 1'"
}

if (!$validInputs)
{
Write-error "$errorString"
}
return $validInputs
}


### Validate the parameters ###
$ifValidParams = ValidateParams;

if (!$ifValidParams) { exit; }

### Define Script variables ###
$2010Server = $2010Server.ToUpper()
$b = $NumDatabases + $DbStartNum
$DeletedItemRetention = $DeletedItemRetention + ".00:00:00"
$MailboxRetention = $MailboxRetention + ".00:00:00"

$SendQuotaLen = $SendQuota.Length
$DBSize = $SendQuotaLen - 2
[decimal] $DBSizeNum = $SendQuota.substring(0,$DBSize)

If ($DbSizeNum -le 9) {$DbExName = [string] $DbSizeNum + "000"}
ElseIf ($DbSizeNum -ge 10 -and $DbSizeNum -le 99) {$DbExName = "00" + $DbSizeNum}
ElseIf ($DbSizeNum -ge 100) {$DbExName = "0" + $DbSizeNum}

If ($DbStartNum -gt 9) {$MdbName = $2010Server + "-DB" + $DbStartNum + "-" + $DbExName}
Else {$MdbName = $2010Server + "-DB0" + $DbStartNum + "-" + $DbExName}
$EdbFilePath = $DbDrive + ":\Exchange\Databases\" + $MdbName + "\" + $MdbName + ".EDB"
$LogFolderPath = $LogDrive + ":\Exchange\Logs\" + $MdbName
$MdbID = $2010Server + "\" + $MdbName

### Create Mailbox Databases Loop ###
Do {New-MailboxDatabase -Name $MdbName -Server $2010Server -EdbFilePath $EdbFilePath -LogFolderPath $LogFolderPath -OfflineAddressBook $OAB -PublicFolderDatabase $PfDb
;Mount-Database $MdbName
;Set-MailboxDatabase –Identity $MdbName –IssueWarningQuota $WarnQuota –ProhibitSendQuota $Sendquota –ProhibitSendReceiveQuota $SendReceiveQuota -DeletedItemRetention $DeletedItemRetention -MailboxRetention $MailboxRetention -RetainDeletedItemsUntilBackup $True
;$DbStartNum++
;If ($DbStartNum -gt 9) {$MdbName = $2010Server + "-DB" + $DbStartNum + "-" + $DbExName}
Else {$MdbName = $2010Server + "-DB0" + $DbStartNum + "-" + $DbExName}
;$EdbFilePath = $DbDrive + ":\Exchange\Databases\" + $MdbName + "\" + $MdbName + ".EDB"
;$LogFolderPath = $LogDrive + ":\Exchange\Logs\" + $MdbName
;$MdbID = $2010Server + "\" + $MdbName
}
Until ($DbStartNum -eq $b)
### END SCRIPT ###






More information on Exchange




Read more!

Monday, September 6, 2010

Pre-Logon Client Choices in Access Gateway Enterprise

By: Rick Rohne

This is an update to a previous article that I wrote about adding a pull-down menu with connection type choices on the logon page for Access Gateway Enterprise Edition. By default Access Gateway Enterprise Edition uses group extraction and EPA scans to determine what kind of connection a user can make. Access Gateway Enterprise also has a client choices screen after authentication that can provide end user selections. These policies may not always offer the best solution for your organization. Therefore configuring a pre-logon client choice may be the best option.

Background

The following are some reasons why you would give users a selection box before authentication:
1. Give users a choice to access their appliacations, desktops, or VPN sessions
2. Allow users to access Sharepoint, OWA, and other clientless web applications using the same url.
3. Allows users to have more control, reducing support calls.
4. Get more out of Access Gateway Enterprise.
I created this video to give you an idea on how this can be used:




Procedure


NOTE: The index.html file mentioned on this article is found under /netscaler/ns_gui/vpn

First create a cookie on the user's workstation

This procedure creates a cookie on the user's workstation which will be evaluated by the session policy. The name of the cookie is NSCookie

1. Download index.html to your workstation.
2. Open the file for editing with your preferred document editor software.
3. Locate the following section:

4. Add the following on the next available line


5. The next line should read:

6. Add storeValues(this);" so that it reads:


Next create the actual pull-down menu


1. On the same index.html page locate the line that reads:

 
2. Add the following code.



(Note: you can add as many OPTIONS as you wish. The Value’s m(x) will be used to match up against a session policy)


3. Save the changes and copy the file to the /netscaler/ns_gui/vpn directory
Note: make sure to backup the original file.


Create a procedure to allow the custom page to survive a reboot


1. Connect to the appliance using an SSH client such as PuTTY.
2. Type shell.
3. Make a directory on the hard drive to hold the custom file.
mkdir /var/customizations
4. Copy the modified page to the new directory.

cp /netscaler/ns_gui/vpn/index.html /var/customizations/


5. Create a startup script file called rc.netscaler under /nsconfig (if one is not already present).
cd /nsconfig
touch rc.netscaler

6. Copy the copy command into rc.netscaler.
echo cp /var/customizations/index.html /netscaler/ns_gui/vpn/index.html >> /nsconfig/rc.netscaler
Next you must modify the session policies to be based on the presence of the cookie instead of the default "true value".

The expression syntax would look similar to that shown in the screen shot below:

add vpn sessionPolicy xMyDT-pol "REQ.HTTP.HEADER Cookie CONTAINS MyDT" XD_ONLY


More Information



The user will then be given a drop down menu on the default logon page. The cookie will be placed on their workstation and evaluated by the session policies. MyDT is the default which should always match the users Default connection while others will match other session policies.



More information on Access Gateway Enterprise

Read more!

Sunday, July 25, 2010

IPad works as a Systems Administrator Tool

By: David Merrell
Last couple weeks I have been traveling back and forth to a client. During my trips I sat in the airport for several hours being bored and really did not want to break out the big 17 inch, 5 Pound laptop to get ahead of some work for a project I was working on. So I was needing something to help to accomplish this while waiting for my plane. The project I was working on was a XenDesktop, XenApp POC for a university in north Texas. My boss has an IPAD and was showing off the Citrix Receiver and Citrix Dazzle a few weeks earlier. I started thinking it would be nice to have a light weight easy to use tool to help me instead of the laptop. Next trip to Texas I picked up a 64 Gb IPAD. The sales guy was asking what I was going to use it for, I told him business mainly and of course he tried to sell me the 3G version. I figured I have an awesome HTC Touch Pro 2, Windows Mobile phone which acts as a wireless access point, so didn't need the 3G charge. Here is the scenario that I used the IPad as an administrator tool: I was able to remote into all the infrastructure servers using for the environment finish configuration using Desktop Connect. I was able to use the Citrix Receiver to connect to a published Citrix XenCenter to administer the XenServers. The Citrix Receiver also allowed me to test the published XenApp applications and desktops; it also allowed me to test the XenDestops. The IPad and the listed apps below is a great set of tools to allow me to provide better support to our customers and be more efficient on the projects I work on.


Here is a list of the apps and descriptions, I installed and use just for the purposes:

APP

Review

Desktop Connect

Desktop Connect is a fast, full-featured desktop viewer, optimized specifically for the IPad. View and control Windows, Mac OSX and Linux computers as if you were sitting in front of them, or observe others as if you were watching over their shoulder.

Desktop Connect is one of the best remote applications I have installed. As a systems administrator the RDP connection was easy to configure and use. The speed of the app is very efficient.

LogMeIn Ignition

One click on your iPad lets you remotely access one or more computers anywhere, anytime.

LogMeIn is a client based app that allows access to systems that may not have the ability to RDP or restricted by firewalls, I mainly use this app for my home network. This app provides another layer of security, it also was easy to setup and configure.

Citrix Receiver

Citrix Receiver for IPad is the perfect business solution for secure access to virtual desktops, applications and data.

As a Systems Engineer that works with XenDesktop, XenApp and XenServer setting up an administration group of apps and XenDesktop to support an environment the Citrix Receiver makes it easier to connect to tools such as the Citrix admin consoles.

Vtrace

Vtrace is a visual traceroute application that shows a list of the networks serves from your machine to a target ip address or hostname on a google map.

This application is a great visual traceroute program, it works well as a network troubleshooting app.

DNS Lookup Tool

DNS lookup tool to find A records, MX records, Name Servers and reverse DNS records for IP addresses and domains.

The description pretty much says it all. At the time of writing this article, this is only an IPhone up but works well with the IPad.

FreePing

FreePing is an ICMP Ping Application. It is designed to have a simple and intuitive user experience.

Again pretty much works as the description says, it also is only for the IPhone at the time of the writing.

Mocha Telnet Lite

Mocha Telnet provides access to servers via Telnet

This is a good tool to telnet to ports on servers to make sure all the necessary ports are accessible.

iXen

This App helps you administrate common tasks on virtual machines running on a Citrix XenServer.

The main functions of this app allow you to Boot, Shutdown, Suspend, Rest and Turn off virtual machines. This is a handy tool if you do not have access to the XenServer console.



Read more!

Monday, June 28, 2010

XenDesktop Deployments...Single or Multiple Hypervisor Infrastructure?

By:Jarian Gibson and Scott Lane


While working on a XenDesktop project in a huge VMware shop, I started thinking if a single hypervisor should be used or if multiple hypervisors should be used in XenDesktop deployments. Then I was on a conference call with Scott Lane, Senior Systems Engineer for Citrix in the Great Plains Area and also a co-author on this post, about the same XenDesktop project and we started discussing thoughts on this. A number of factors came to mind like cost of the hypervisor (VMware licenses for the XenDesktop project are adding a nice chunk of change to the cost of the deployment), hypervisor features, etc. In this blog post I am going to talk about things to consider about different hypervisors for XenDesktop deployments.

I often go into shops that already have large VMware infrastructures deployed and talk about XenDesktop. When I'm talking to the customer or potential customer about XenDesktop I always mention that with XenDesktop VDI, Enterprise, or Platinum Editions they will also get XenServer Enterprise Edition. This always gets mixed results. Most think I'm trying to push VMware out the door when I talk about XenServer. This is not the case at all. When I talk about XenServer I am focused on the XenDesktop environment and nothing else in their environment. I tell the customer that you may want to look at XenServer for the provisioned XenDesktop virtual Windows desktops and XenApp servers and then use their existing VMware infrastructure for the XenDesktop infrastructure components. Use XenServer that is included with XenDesktop for your XenDesktop Windows desktop and XenApp server infrastructure and continue to use your VMware infrastructure for everything else.

I also talk about the open architecture of XenDesktop and that they can choose between Citrix XenServer, Microsoft Hyper-V, and VMware vSphere hypervisors for the XenDesktop virtual desktops. I talk about Hyper-V as another option and the benefits of using Hyper-V for the hypervisor in XenDesktop deployments especially when the customer is talking about deploying Windows 7 and Windows 2008 virtual machines in their XenDesktop infrastructure. Some think that having multiple hypervisors is too much to manage or there is a big learning curve. Most customers I have worked with that are strong in virtualization find XenServer pretty easy to learn. With tools like System Center Virtual Machine Manager that can manage ESX/vSphere and Hyper-V from a single console make management of multiple hypervisors easy for multiple hypervisor deployments. When System Center Virtual Machine Manager supports management of XenServer, all three hypervisors will be managed from a single console.

XenDesktop deployments on Citrix XenServer considerations:
XenDesktop deployments on Microsoft Hyper-V R2 considerations:
  • System Center Virtual Machine Manager is needed to manage hosted virtual desktops

  • Server and Desktop administrators who already use System Center products will already be familiar with the look and feel of System Center Virtual Machine Manager console

  • System Center Essentials 2010 could be used for smaller XenDesktop deployments (for XenDesktop deployments under 500 seats when supported)

  • Management server (System Center Virtual Machine Manager or Essentials 2010) can be single point of failure for management of hosted virtual desktops

  • Microsoft Hyper-V Server 2008 R2 Edition is free with features like Live Migration, Host Clustering, etc but needs System Center Virtual Machine Manager or Essentials 2010 to manage hosted virtual desktops

  • System Center Virtual Machine Manager or Essentials 2010 console needs to be installed on XenDesktop Delivery Controllers and Provisioning Servers for management and for use with XenDesktop Setup Wizard

  • Windows 7 virtual desktops and XenApp servers running on Windows 2008 have integration components built-in to the operating system. No need for 3rd party virtual machine tools to install and maintain.

  • Hyper-V can direct boot VHD files to update Provisioning Services tools
  • Legacy NIC needed for network boot/Provisioning Services and Synthetic NIC for all other traffic

  • Network boot enabled in virtual machine settings

  • Windows 7 and Windows 2008 on Hyper-V are better together

  • Citrix and Microsoft relationship
  • System Center Virtual Machine Manager for mixed vSphere and Hyper-V deployments with XenServer support coming in the future for a possibly mixed environment of all 3 hypervisors

  • Having Hyper-V already in place makes you already prepared for RemoteFX and Dynamic Memory that are coming in service pack 1

XenDesktop deployments on VMware vSphere considerations:
So as you can see a number of factors come into play when choosing a hypervisor for your XenDesktop infrastructure. Some customers I have worked with have stayed with their current hypervisor and kept a single hypervisor infrastructure all on VMware vSphere. While other customers I have worked with have gone with multiple hypervisor infrastructures having the XenDesktop infrastructure components on VMware vSphere and the virtual desktops on Citrix XenServer. I have even had one customer put everything relating to Citrix on Citrix XenServer and kept the rest of their infrastructure on VMware vSphere. I will be doing an install next month in a pure XenServer environment (They have been running Xen since long before the Citrix acquisition). The demo lab at my office and what we use for workshops is a mix of Citrix XenServer for the virtual appliances and Microsoft Hyper-V R2 for everything else. Microsoft Hyper-V R2 is getting more consideration and interest lately and I expect to start doing more and more XenDesktop deployments on Hyper-V soon.

For XenDesktop deployments do you stick with a single or have multiple hypervisors? Every environment is different and everyone has their own take on this. With the way the economy has been customers are looking at other options instead of paying a premium for what they currently have. Especially since cost for and deployment of a XenDesktop infrastructure are a huge factors these days. Citrix XenServer and Microsoft Hyper-V R2 are getting more and more interest and gaining ground every day as the feature sets become more and more comparable with VMware vSphere. With XenDesktop having an open architecture you have options when it comes to the hypervisor. The hypervisor is becoming a commodity anyway, right?

If you have found this article interesting or if you have any other insights, please feel free to leave comments on this article.

Read more!

Thursday, June 3, 2010

Exchange 2007 Rollup Causes “Outlook Web Access was unable to initialize” errors

By:Rik Hoffelder
If you’re reading this chances are you have applied a rollup to Exchange 2007. In my case it was Rollup 4 for Exchange 2007 SP2. After applying the update OWA users began experiencing errors accessing the login page stating “Outlook Web Access was unable to initialize. Contact your administrator.”

When this occurred MSExchangeOWA wrote a FormsRegistry error with Event ID 4 into that application log. Specifically it stated the “More than one forms registry is named Premium” as shown below.



After researching the problem on the web and finding nothing I did a little investigating and found the problem to be a simple case of an installer not cleaning up after itself. In this case a directory named Copy of premium existed in the same sub-directory as the premium directory. This is typically located under C:\Program Files\Microsoft\Exchange Server\ClientAccess\Owa\forms.



To resolve the problem I simply deleted the Copy of premium directory then ran IISRESET /NOFORCE. This resolved the issue in my case. I can’t say it will work for everyone, but since there is very little information about this error anywhere, I thought I would share at least one solution.





More information on Exchange




Read more!
Loading...
Microsoft Virtualization, Citrix, XENServer, Storage, iscsi, Exchange, Virtual Desktops, XENDesktop, APPSense, Netscaler, Virtual Storage, VM, Unified Comminications, Cisco, Server Virtualization, Thin client, Server Based Computing, SBC, Application Delivery controllers, System Center, SCCM, SCVMM, SCOM, VMware, VSphere, Virtual Storage, Cloud Computing, Provisioning Server, Hypervisor, Client Hypervisor.