Monday, December 8, 2014

Things you think you thought you knew...

So I always thought I knew how to tie my shoes. Of course I have to double-knot them a lot because they because untied. Little did I know I was doing it wrong! This TED talk from Terry Moore shows where most of us go wrong. If only I knew the rabbit hole was a trick all along I could have been tying my shoes the correct way!

Saturday, December 6, 2014

Moving that DataStore, is there still someone attached?

While migrating a Citrix XenApp datastore isn't difficult (see How to move or migrate data store) can can rather quickly be scripted across all your farm servers, one question always remains... did I miss one?

If you try to take your original DB and perform the SQL Management Studio action "Take Offline" and all you get is a progress wheel that, well, never progresses, you may have one or more connections still active.

So how do you check? If you open a new query in SQL Management Studio prior to trying to take the DB offline you type and execute the command "sp_who" - the results of this will show all connections to the SQL Server including the source, user, and database. If your server is dedicated to your SQL infrastructure you can quickly parse this list to see what servers may have been missed.

Alternatives if you have a shared environment could be the query below that will tell you the number of connections active to each DB:

SELECT DB_NAME(dbid) as DBName, COUNT(dbid) as NumberOfConnections, loginame as LoginName, nt_domain as NT_Domain, nt_username as NT_UserName, hostname as HostName FROM sys.sysprocesses WHERE dbid > 0 GROUP BY dbid, hostname, loginame,nt_domain,nt_username order by NumberOfConnections DESC

Finally, you could combine the two options and build a temporary DB to see only the connections open to your data store. 

There are a number of samples on the web for this method, one such is listed below. Just change the DB name 'master' to the DB name of your Citrix XenApp DataStore. 

DECLARE @temp TABLE(spid int , ecid int, status varchar(50),
                     loginname varchar(50),   
                     hostname varchar(50),
blk varchar(50), dbname varchar(50), cmd varchar(50), request_id int) 
INSERT INTO @temp  
EXEC sp_who
SELECT * FROM @temp WHERE dbname = 'master'

Wednesday, December 3, 2014

The PageFile - Oh My!

The page file should be two times the amount of RAM!

The page file should be one and one-half the size of RAM!

The system should manage the size of RAM!

It is 2014, who needs a page file!


You may hear any of the above from colleagues or clients in today's day and age. The long and short of it is that you cannot easily and accurately compute the the needed page file ahead of time in many environments due to different software that is used. Below you will find some references as well as an excerpt from a write up I wrote a couple years ago for sizing virtual memory in a specific environment.

Pushing the Limits of Windows: Virtual Memory (really the be-all guide)

How to use the DedicatedDumpFile registry value to overcome space limitations on the system drive when capturing a system memory dump (I used this on the 2012 build to eliminate the tie between dumps and PF)

How To Size Page Files on Windows Systems (good reference)

The Pagefile Done Right! (my go-to guide)

PAGE FILE SIZING

“Perhaps one of the most commonly asked questions related to virtual memory is, how big should I make the paging file? There’s no end of ridiculous advice out on the web and in the newsstand magazines that cover Windows, and even Microsoft has published misleading recommendations.” –Mark Russinovich
The following items hold true in regards to the Windows Page File.
1.       Even systems with large amounts of RAM benefit from the presence of a page file.
3.       There is a performance hit to a system whenever the operating system automatically resizes the page file.
4.       Excessive use of the page file will result in poor system performance as the speed of disk is much slower than that of RAM.
5.       Never stripe paging files (you can have more than one) across multiple volumes on the same physical disk. This can lead to performance issues.
6.       Splitting a page file across multiple physical disks will increase performance.
7.       “To optimally size your paging file you should start all the applications you run at the same time, load typical data sets, and then note the commit charge peak (or look at this value after a period of time where you know maximum load was attained). Set the paging file minimum to be that value minus the amount of RAM in your system (if the value is negative, pick a minimum size to permit the kind of crash dump you are configured for). If you want to have some breathing room for potentially large commit demands, set the maximum to double that number.” –Mark Russinovich



Tuesday, December 2, 2014

Hidden Devices Causing you the Blues?

When using Citrix PVS (or often when changing hardware on virtual machines) you may often run into instances where you need to remove phantom devices. But how do you know these exist? Device Manager doesn't show them by default. Microsoft outlines how to do this in an old support article.


  1. Launch a command prompt with elevated permissions. 
  2. At the command prompt, type the following lines, pressing ENTER after each line
    set devmgr_show_nonpresent_devices=1
    cd\%SystemRoot%\System32
    start devmgmt.msc
  3. In the Device Manager View Menu, select Show Hidden Devices



Reference: KB241257

Monday, December 1, 2014

File Selection Input Window

Sometimes in my scripting ways I need to solicit a location from a user with for reading or writing data. Below is a simple function I have used when I need a user to select a Comma Separated Values file. It creates a simple dialogue box showing .CSV files in a particular location. It will either return the selected file name or an error. It is a simple starting point that can be expanded upon as needed.


Function Select-FileWindow
{
      param(
      [string]$Title = "Select CSV",
      [string]$Directory = "C:",
      [string]$Filter = "CSV Files (*.csv)|*.csv"
      )
     
      [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms"| Out-Null
      $objForm = New-Object System.Windows.Forms.OpenFileDialog
      $objForm.InitialDirectory = $Directory
      $objForm.Filter = $Filter
      $objForm.Title = $Title
      $objForm.ShowHelp = $true
      $Show = $objForm.ShowDialog()
      If ($Show -eq "OK")
      {
            Return $objForm.FileName
      }
      Else
      {
            Write-Error "Operation cancelled by user."
      }
}