Tag Archives: PowerShell

Accurately checking the Citrix PVS “cache in Ram, Overflow to disk” RAM cache size

Citrix_Provisioning_Services_ImplementationCitrix Provisioning services “Cache in RAM, overflow to disk”, even with it’s challenges is something I’ve always felt was a great idea, hell, I foresaw it’s implementation back in 2012!

Not withstanding the issues that can occur when the cache is heavily in use, it’s a great piece of technology. One of the features you see on twitter repeatedly is trying to report on the exact size of the PVS cache in RAM.

Many blogs and scripts (Matt’s here, as an example) will take the raw performance counter details for Non Paged Pool memory and assume this is the size of the cache. This is faulty logic, but close enough. It’s like looking into a can of beans and trying to determine which one gave you gas.

The Non paged Pool is a collective pool of memory used by the system that guarantee’s the services using it (drivers, etc) that the contents will never reach the disk and will always be maintained in memory. As an example, imagine you created your own disk driver, but the disk driver tried to reference it’s memory and it had since been flushed to the disk…. Chicken and Egg stuff!

Microsoft has a fairly clear description here:

The memory manager creates the following memory pools that the system uses to allocate memory: nonpaged pool and paged pool. Both memory pools are located in the region of the address space that is reserved for the system and mapped into the virtual address space of each process. The nonpaged pool consists of virtual memory addresses that are guaranteed to reside in physical memory as long as the corresponding kernel objects are allocated.

So with this in mind, taking a total of the Non Paged Pool memory and assuming it’s PVS is “OK”… But not accurate. Many other sources can bloat that memory cache, particularly in x64 systems where limits on these pools are now enormous compared to the tiny pools we had to deal with in x86 architectures.

Nerdy digression aside, if you REALLY want accurate information on what’s going on inside of this pool. You need to grab a copy of Poolmon from the Windows Driver Kit (WDK). Download the WDK, install it and you’ll find your poolmon in:

C:\Program Files (x86)\Windows Kits\10\Tools\x64\poolmon.exe

Once you have a copy, fire up poolmon and you’ll see in all their glory.

pvs

Pro tip: Press “p” once to sort my non pooled, then “b” to sort by bytes used.

Each pool tag and the respective space they are using. Interestingly, the Citrix caching technology seems to use the “VhdR” pooltag allocation. There’s also a Microsoft Pool tag for this (http://blogs.technet.com/b/yongrhee/archive/2009/06/24/pool-tag-list.aspx) but the case sensitivity differences between VhdR and VHDr may make all the difference.

I did reach out to Citrix on this one, but they didn’t provide any further insight.

Any-who, if you want to see the size of your PVS cache accurately? Use PoolMon. Here’s a quick script using poolmon to get the GB value back:

$poolmonpath= "d:\poolmon.exe"
$poollog= "$env:temp\poolmon.txt"
if(test-path $poollog){Remove-Item $poollog}
Start-Process-FilePath $poolmonpath -ArgumentList "-n $poollog" -Wait
((Get-Content $poollog | ? {$_ -like "*VhdR*"}) -split "\s+")[6] /1gb
if(test-path $poollog){Remove-Item $poollog}

Adding a list of Authorised files to RES Workspace Manager Building Block

Windows_PowerShell_iconThis is just a quick article on how to search for exe’s recursively in a specific path and add them to an RES Workspace Manager building block to be imported back in.

I needed to do this recently as the customer in question had an application that lived on a network share and after 14+ years of development in this style, everyone was afraid to move it!

Steps to use this script:

  • Export an existing building block for the application you wish to authorize
  • Ensure the exported building block has at least one authorized file
  • Modify the $import and $exportbuildingblockpath
  • Modify the $exedirpath to be the path you wish to search recursively for exe’s.
$importBuildingBlockPath = 'H:\path\bb.xml'
$exportBuildingBlockPath = 'h:\path\export.xml'
 
$alreadyauth=@()
$ExeForAuth=@()
$exedirpath = "\\servername\Share\APPS"
 
 
Get-ChildItem -Recurse $dirpath | ?{!($_.psiscontainer) -and $_.Extension -like ".exe"}  | %{
    $ExeForAuth+=$_.fullname.ToLower()
}
 
 
[xml]$bb = Get-Content $importBuildingBlockPath
 
 
$bb.respowerfuse.buildingblock.application.appguard.authorizedfiles.authfile | %{
    $alreadyauth+=$_.authorizedfile.tolower()
}
 
 
Compare-Object $alreadyauth $ExeForAuth | ? {$_.SideIndicator -eq "=>"} | % {
    $newnode=$bb.respowerfuse.buildingblock.application.appguard.authorizedfiles.authfile[0].Clone()
    $newnode.authorizedfile=$_.inputobject.tostring()                                                                                     
    $newnode.description="Auto Appended item via script"                                                                                        
    $newnode.process="*"                                                                                          
    $newnode.learningmode="no"                                                                                               
    $newnode.enabled="yes"   
    $bb.respowerfuse.buildingblock.application.appguard.authorizedfiles.AppendChild($newnode)
}
 
$bb.save($exportBuildingBlockPath)

Viewing open files on a file server from powershell.

/wp-content/uploads/2011/03/windows_powershell_icon.png?w=58&h=58&h=58So this is a situation you should all be aware of in an SBC / VDI environment, despite all warnings, you’ve redirected folders to your network drive and your file servers are screaming in agony?

Having been in this situation recently, I needed to audit and report on the types of files open on the file server, my hunch was a certain select number of users were running applications (like *gulp* lotus notes) from the network share.

Disappointed with the powershell scripts on the interwebs, I decided to write my own function to perform this task:

[sourcecode language=”powershell”]
function get-openfiles{
param(
$computername=@($env:computername),
$verbose=$false)
$collection = @()
foreach ($computer in $computername){
$netfile = [ADSI]"WinNT://$computer/LanmanServer"

$netfile.Invoke("Resources") | foreach {
try{
$collection += New-Object PsObject -Property @{
Id = $_.GetType().InvokeMember("Name", ‘GetProperty’, $null, $_, $null)
itemPath = $_.GetType().InvokeMember("Path", ‘GetProperty’, $null, $_, $null)
UserName = $_.GetType().InvokeMember("User", ‘GetProperty’, $null, $_, $null)
LockCount = $_.GetType().InvokeMember("LockCount", ‘GetProperty’, $null, $_, $null)
Server = $computer
}
}
catch{
if ($verbose){write-warning $error[0]}
}
}
}
Return $collection
}
[/sourcecode]

The function above (get-openfiles) has been written to accept an array of servers to the command line and it will return the following items:

  • The ID of the open file.
  • The server it’s open from.
  • The username who has the file open.
  • The amount of locks the file has.

A couple of quick examples for using this command are below:


Retrieving open files from server1:


full

[sourcecode language=”powershell”]get-openfiles -computername server1 | select server,itempath,lockcount[/sourcecode]



Retrieve a count of open files that end with the nsf file type (Lotus Notes):


count

[sourcecode language=”powershell”](get-open files -computername server1,server2 | ? {$_.itempath -like "*.nsf*"}).count()[/sourcecode]



Retrieve a report of total open files on a number of file servers:


report

 

[sourcecode language=”powershell”]get-openfiles -computername server1,server2,server3,server4,server5 | group -property server[/sourcecode]

 

Monitoring Storage disk queue’s and IO with PowerShell

/wp-content/uploads/2011/03/windows_powershell_icon.png?w=58&h=58&h=58Here’s one that used to bother me alot. The problem usually went as follows:

“Your XenApp servers have very high disk queue’s and IO”

“What’s causing it?”

“dunno…”

With Server 2008, the task manager’s resource monitor feature will help you find these items. But in server 2003 this was a perilous task. The specific details for disk io per process are stored in performance monitor under each specific process running. Trying to analyse each process was a massive pain, but powershell can do some very clever work to help alleviate this!

I wrote two quick functions which act similar to “top” in linux for giving an on screen view, updating at interval of what exactly is creating IO activity. These two functions are:

get-IODataBytes:

storageio

Get-IODataOperations

storageioops

The code for these functions are below:

[sourcecode language=”powershell”]
function get-iodatabytes{
$result=(get-counter -counter "Process(*)IO Data Bytes/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Bytes/sec";Expression={[math]::Round($_.cookedvalue,0)}},@{Name="IO Data KBytes/sec";Expression={[math]::Round($_.cookedvalue / 1024,0)}} | sort -Descending "IO Data Bytes/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

FUnction get-IODataOperations {
$result=(get-counter -counter "Process(*)IO Data Operations/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Operations/sec";Expression={[math]::Round($_.cookedvalue,0)}} | sort -Descending "IO Data Operations/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

[/sourcecode]

if you wish to loop one of these functions, simply use the following code:

[sourcecode language=”powershell”]
while ($true){
get-iodataoperations
start-sleep 1
}
[/sourcecode]

Silently installing the Citrix Edgesight ActiveX plugin

Just a really quick blog post on how to silently install the reporting agent inside your environment.

Log into a server / client without the EdgeSight plugin installed, and browse to the edgesight website. Once logged in, you will receive the usual prompt to install the software:

Install the software and ensure it works, then fire up a command prompt and browse down to “c:windowsdownloaded program files”. Once in this folder, a DIR will reveal the ActiveX plugin “csmdbprov.dll”.

Now simply copy this file out to shared storage:

Once done, now its scripting time!

Below are two examples in batch (.bat , .cmd) or PowerShell (.ps1) for achieving this:

(please amend h:csmdbprov.dll to the path you use)

Batch:

[sourcecode language=”text”]
copy h:csmdbprov.dll "c:windowsdownloaded program files"
regsvr32 /s "c:windowsdownloaded program files"
[/sourcecode]

Powershell:

[sourcecode language=”powershell”]
if (test-path h:csmdbprov.dll){
copy-item H:csmdbprov.dll ‘C:WindowsDownloaded Program Files’ -Force
start-process regsvr32 -ArgumentList "/s ""C:WindowsDownloaded Program Filescsmdbprov.dll""" -wait
}
[/sourcecode]