String Theory

Mastering the laws of physics with Windows PowerShell

Browsing Posts tagged PowerShell

I recently gave a presentation on the Citrix XenApp cmdlets for the Atlanta Citrix User Group.  For the presentation I wanted to show a real world example of the cmdlets in use. I decided to take a script that I wrote in July of 2007 ,which is still in use today, and convert it to use the new XenApp PowerShell cmdlets.  Shown below is the original script.

The purpose of the script is to automatically create a published desktop for our XenApp servers as they are built.  It uses MFCOM to perform the work.  One of the pain points in this script is that I had to actually copy the icon from an existing published desktop. This is a problem that I don’t have with the cmdlets.

#=============================================================================
#= Script Name:      Citrix Admin Desktop Publishing Script
#= Created On:       07/11/2007
#= Author:           Mark E. Schill
#= File:             Publish-Desktop.ps1
#= Usage:
#= Version:          1.0
#= Purpose:          Publishes an Admin Desktop on the server it is run from.
#= Requirements:       Must be run on a Citrix server in the same farm
#= Last Updated:     07/11/2007
#= History:
#=                   07/11/2007 1.0 - Initial Revision
#=
#=                        Copyright (C) 2007 Mark E. Schill
#==============================================================================

function Publish-Desktop( [string]$ServerName)
{
    $CPSReferenceApp = New-Object -comOBject MetaFrameCOM.MetaFrameApplication
    $CPSReferenceApp.Initialize(3, "Applications/Admin/Desktops/WMT13-CTX-DC1 Desktop")
    $CPSReferenceApp.LoadData($true)
    $CPSReferenceIcon = $CPSReferenceApp.WinAppObject.IconObject

    $ServerName = $ServerName.ToUpper()
    $CPSFarm = New-Object -ComObject MetaFrameCOM.MetaFrameFarm
    $CPSFarm.Initialize(1)
    $CPSApp = $CPSFarm.AddApplication(3)
    $CPSApp.AppName = "$ServerName Desktop"
    $CPSApp.Description = "Admin Desktop for Remote Administration"
    $CPSApp.ParentFolderDN = "Applications/Admin/Desktops"
    $CPSApp.PNFolder = "Admin\Desktops"
    $CPSApp.WinAppObject.DefaultInitProg = ""
    $CPSApp.WinAppObject.DefaultWorkDir = ""
    $CPSApp.WinAppObject.DefaultWindowColor = 4 # 32 Bit
    $CPSApp.WinAppObject.DefaultWindowType = 6 # MFWINWindowPercent
    $CPSApp.WinAppObject.DefaultWindowScale = 95 # 95%

    $CPSApp.WinAppObject.PNAttributes = 8
    $CPSApp.WinAppObject.SetIconBitmaps( $CPSReferenceIcon.IconMaskSize, $CPSReferenceIcon.IconMaskBitmap, $CPSReferenceIcon.IconDataSize, $CPSReferenceIcon.IconDataBitmap)
    $CPSApp.AddUser( 1, "CDC", 4, "CTX-Admins")
    $CPSApp.AddUser( 1, "CDC", 4, "CTX-Support")
    $CPSApp.SaveData()
    $CPSAppBinding = New-Object -ComObject MetaFrameCOM.MetaFrameAppSrvBinding
    $CPSAppBinding.Initialize(6,$ServerName,$CPSApp.DistinguishedName)
    if ($CPSAppBinding)
    {
        Write-Host "Publishing"$CPSApp.BrowserName"on $ServerName" -foregroundcolor Green
        $CPSApp.AddServer($CPSAppBinding)
        $CPSApp.SaveData()

    }
    else
    {
        Write-Host "Unable to create App Binding" -foregroundcolor red
    }

}

Publish-Desktop("$env:COMPUTERNAME")

Shown below is the new “script”. As you can see it is actually a one-liner if you take out the function stuff. Also I don’t have the icon issue because it automatically creates the correct icon.

function Publish-Desktop( [string]$ServerName)
{
	New-XAApplication -ApplicationType ServerDesktop -DisplayName "$ServerName Desktop" -FolderPath "Applications/Admin/Desktops" -Description "Admin Desktop for Remote Administration" -ClientFolder "Admin\Desktops" -WindowType "95%" -ColorDepth TrueColor -Accounts "$ServerName\Administrators" -Servernames $Servername
}

I am one of the guest judges for the Scripting Games 2010 occurring right now at http://2010sg.poshcode.org and http://blogs.technet.com/heyscriptingguy/. I am currently working on the Beginner Event 4 which asks the user to read the Environment Variables to get the number of processors in the machine.

This evening I am finding myself in constant conflict with my own principals as I grade these entries. In accordance with the spirit of the Scripting Games, I am grading the entries based on those guidelines including “Anything that goes beyond the bare minimum requirements of the scenario”, but it is taking all of my strength not to give them one star and write, “Dude, you know you can do that with one line.” These are games after all, so maybe I can convince the Scripting Guys next year to do the “2011 Scripting Reality Challenges”. What do you think?

Yours truly,

Mark

As promised here is my PowerPoint presentation and demo code for the presentation I gave at the Atlanta Citrix User Group titled “Managing XenApp with Windows PowerShell”

Presentation: Managing XenApp with Windows PowerShell

Demo Code: Demo.ps1

A New Project

1 comment

I am a follower, or rather, I attempt to follow the GTD Methodology. The method is based on the principle that you need to take all the tasks that are floating around in your mind and record them in an external system. That way, your mind is free from the job of remembering everything that needs to be done. No more of the “I know I needed to do something, but I can’t remember what it was.”

Originally I was using Remember the Milk (RTM) to track all of my tasks. It is a great website and they have clients for everything. But there were a few things that I didn’t like. RTM didn’t support task statuses and the font used in the iPhone application was huge. Now that may not sound like a big deal, but when you are trying to go through your task list and can only see 5 or so tasks on one screen you have to do a lot of scrolling.

I did some searching and settled on a site called ToodleDo. Its a great site and has lots of features. I won’t go into them, but please take a look and see for yourself. After I got it all set up with all of my personalized folders and tags and other such settings I realized that they didn’t have any  PowerShell interfaces. They have plenty of other connections listed on their site including a couple of .NET libraries.

I almost always has a PowerShell window open on whatever computer I am on at the time so I thought a PowerShell module would be perfect. Especially since a lot of my tasks are related to PowerShell. And I wanted the experience and practice of creating a “production class’” modules that others would benefit from.

I started on this module and have been working on it for a couple of months off and on. When I got finished with the function to add a task to the system I decided it was ready enough for others to start looking at it and created a CodePlex project.

I am affectionately calling it “ToodlePosh” (I couldn’t come up with a better name) and it is located at http://toodleposh.codeplex.com/. Please feel free to take a look at it and play with it.

The inaugural meeting of the Atlanta PowerShell User Group will be held on Tuesday March 16th from 6:00 to 8:00 PM. You can sign up now at http://powershellgroup.org/atlanta.ga.

Our first meeting will be a script club.

What is a script club you ask? You bring an idea for a script, and ask your fellow PowerShell users for help getting the script written. If it’s PowerShell, its covered — just bear in mind that it may be hard to test things like Exchange scripts or Active Directory management scripts unless you have a nice virtual lab on your laptop.

What are the Rules of Script Club?

  1. You always talk about script club
  2. You always talk about script club
  3. If someone asks for help, and you can help, you help
  4. Two people help one person at one time
  5. One module per person per night
  6. All scripts, all PowerShell
  7. Scripts will be as short as they can be
  8. If this is your first time at Script Club, You have to script!

Pizza will be provided.

Our meeting will be held at the New Horizon’s training center at 211 Perimeter Center Parkway, Suite 200, Atlanta, GA 30346. Click here for directions and a map.

Update: Updated with correct date.

[System.Version]

No comments

This afternoon there was a discussion about determining the version of PowerShell installed on the local system. Each of us had our own answer. Someone mentioned the [System.Version] .Net class. Its a relatively small class that might you might find useful.

Lets take the Product Version of the PowerShell executable installed on my Windows 7 workstation and get the properties of the class.



$Version = [Version][Diagnostics.FileVersionInfo]::GetVersionInfo(
   $PSHome\PowerShell.exe).ProductVersion
$Version | Select *

And this is what we get:

Major         : 6
Minor         : 1
Build         : 7100
Revision      : 0
MajorRevision : 0
MinorRevision : 0
 

System.Version also implements operators so you can use the PowerShell comparison operators. For example lets say you want to compare the current version of PowerShell to determine if its a later release the CTP3. Just using the following statement.

$Version -gt [System.Version]"6.1.6949.0"

		

Post Your PowerShell Profile!

Posted using ShareThis

I have recently been following the whole Getting Things Done (GTD) methodology created by David Allen. So far it has actually been helping me get organized. One of the things it mentions is to get tasks out of your head and down on “paper”. Otherwise you will be forgetting tasks and wondering what you are forgetting. Since I am always in PowerShell and most of my tasks now are PowerShell related. You know, “I have to check out PowerBoots” “Wouldn’t it be cool to do feature x in my script?”. So I decided to create a PowerShell advanced function that I can use to create Outlook tasks.

You can grab the code at: http://www.poshcode.org/829

BitWise Operators

2 comments

Today we will take a look at the Bitwise Operators in Windows PowerShell and how you can manipulate them for your needs.  First we will get some insight into the enumeration. Let’s begin by looking at the values for the [System.IO.FileAttributes] enumeration which provides attributes for files and directories.

As you can see from the table below each member corresponds to a different attribute that you can apply to files and directories. Some of these are common values that you see daily such as ReadOnly and Hidden, but others are not so common. I won’t go into the meaning of each of these, but if you are interested you can review them on the MSDN site here. Each value, in decimal, is a power of 2 greater than the previous value. To add attributes you add the binary value. So the attributes for a file that is ReadOnly and Hidden would be "1" + "10" = "11" or 3.

An interesting note is that given any enumeration value there can be only ONE possible combination of values that will add up to the enumeration value.

Member Name Binary Value Decimal Value
ReadOnly 1 1
Hidden 10 2
System 100 4
Directory 10000 16
Archive 100000 32
Device 1000000 64
Normal 10000000 128
Temporary 100000000 256
SparseFile 1000000000 512
Compressed 10000000000 2048
Offline 100000000000 4096
Encrypted 1000000000000 16384

So. Enough for the theory. Let’s have fun.

Determining if an attribute is set

The first task we want to accomplish is checking to see whether an attribute is set on a specified file. In this case we are using a file called "test.txt" with the Hidden and ReadOnly attributes set. First we get the file information and attributes. Then we use the -band bitwise operator to compare the objects.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
if ( $File.Attributes -band [System.IO.FileAttributes]::Hidden )
{ Write-Host "Hidden Attribute Set" }

With the "-band" operator each binary value is compared and in each position if a 1 is present in both numbers then a 1 is returned. If not, a 0 is returned. So for our example "11 -band 10" is equal to 10 because a 1 is in the second position in both numbers. The way that enumerations are setup dictate two possible values for this comparison. Either the returned value is equal to the attribute being compared or 0, indicating that the attribute is not set.

Setting an attribute

The next task we want to perform is setting an attribute. We are going to use the same file we used in the previous example and set the System attribute. For this task we are going to use the -bor operator.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
$File.Attributes = ( $File.Attributes -bor [System.IO.FileAttributes]::System )
$File.Attributes

Here, by using the "-bor" operator each binary value is compared and in each position if there is a one present in either number then a one is returned for that position. It’s like a light switch. If it is turned on in either number then it is turned on in the resulting output.  Using this analogy we are flipping on the switch that corresponds to the System attribute.

Removing an attribute

The last task is removing an attribute. For this example we are using the "-bxor" operator. This operator is like a two-way light switch. If you turn on one light switch, the light is on. If you then turn on the other switch, the light turns off.  So you can probably see the issue. If you run the following script a couple of times on the same file you will notice that the System attributes gets turned on or off each time you run it.

$File = Get-ChildItem .\test.txt -Force
$File.Attributes
$File.Attributes = ( $File.Attributes -bxor [System.IO.FileAttributes]::System )
$File.Attributes

This is good if you want to set an attribute to the opposite of the current setting. However if you want to just remove an attribute you will need the following script.


$File = Get-ChildItem .\test.txt -Force
$File.Attributes
if (  $File.Attributes -band [System.IO.FileAttributes]::System)
{ $File.Attributes = ( $File.Attributes -bxor [System.IO.FileAttributes]::System )  } $File.Attributes

We use the "-band" operator to make sure the option is set and then unset it using the "-bxor" operator.

Powered by WordPress Web Design by SRS Solutions © 2010 String Theory Design by SRS Solutions