PowerShell and XenDesktop
Posted by: Richard Siddaway
Jonathan Medd will be presenting tomorrow @ 8.30 BST on PowerShell and XenDesktop
Details from
Jonathan Medd will be presenting tomorrow @ 8.30 BST on PowerShell and XenDesktop
Details from
Want some free ebooks?
Check out
You may have noticed that I mention WMI from time to time
Up to now WMI has been a Windows technology. Powerful but limited to Windows. WMI has taken a giant step into the big bad world with the creation of OMI – Open Management Infrastructure thats WMI for non-Windows systems
Details are here
http://blogs.technet.com/b/windowsserver/archive/2012/06/28/open-management-infrastructure.aspx
and
https://collaboration.opengroup.org/omi/
Expect more on this in the months to come
Many scripting languages require you explicitly write out to screen – VBScript was an example.
This leads to PowerShell that looks like this
Get-Service |
foreach {
Write-Host $_.Name, $_.Status
}
This is bad on so many levels.
Firstly you are doing too much work. Secondly you are emitting text not objects. Thirdly you are doing too much work.
Get-Service |
Format-Table Name, Status –AutoSize
gives a much better result and if you are working at the prompt can be aliased to
gsv | ft Name, Status –a
The last act of the pipeline is to pass the data to Out-Default which performs the screen writing. Write-Host also passes data to Out-Default which effectively terminates the pipeline.
You should always format the data for display as far into the processing as you possibly can. Once you have called a format cmdlet or Write-Host you have terminated the pipeline.
The best you will get is the text representation that would have been displayed on screen. The worst is garbage output.
So if you want to create a HTML report then
Get-Service |
Select Name, Status |
ConvertTo-Html |
Out-File test.htm
Invoke-Item test.htm
Stick with objects and let the pipeline do the work
When: Wednesday, Jul 4, 2012 8:30 PM (BST)
Where: Virtual*~*~*~*~*~*~*~*~*~*
Jonathan Medd will be talking about using PowerShell to administer a XenDesktop environment
Notes
Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:
If you still cannot enter the meeting, contact support
Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.
A question brought it home to me that WMI property names don’t always mean what you might think they mean – this is also true of other objects but I tripped over this one with WMI so we’ll stick with that.
PS> Get-CimInstance -ClassName Win32_Desktop -Filter "Name LIKE ‘%Richard’" |
>> Format-List ScreenSaver*
>>
ScreenSaverActive : True
ScreenSaverExecutable : C:\Windows\system32\PhotoScreensaver.scr
ScreenSaverSecure : True
ScreenSaverTimeout : 600
The ScreenSaverActive property doesn’t mean that the screen saver is currently active – it means that one has been set! This is doubly confusing because the documentation states
Screen saver is active.
Which would lead you to think that is was actually running!
The ScreenSaverSecure means that a password has been set to unlock the system once the screen saver kicks in & ScreenSaverTimeout is the idle time in seconds before the screen saver kicks in. The executable is the screen saver that will be used.
If you want to get the information with the WMI cmdlets use
PS> Get-WmiObject Win32_Desktop -Filter "Name LIKE ‘%Richard’" |
>> Format-List ScreenSaver*
>>
ScreenSaverActive : True
ScreenSaverExecutable : C:\Windows\system32\PhotoScreensaver.scr
ScreenSaverSecure : True
ScreenSaverTimeout : 600
When: Wednesday, Jul 4, 2012 8:30 PM (BST)
Where: Virtual*~*~*~*~*~*~*~*~*~*
Jonathan Medd will be talking about using PowerShell to administer a XenDesktop environment
Notes
Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Troubleshooting
Unable to join the meeting? Follow these steps:
If you still cannot enter the meeting, contact support
Notice
Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.
I recently (1 June) showed how to discover the user profiles on your system. Now its time to delete them.
function remove-profile { param ( [parameter(Mandatory=$true)] [string]$username ) $user = Get-CimInstance -Class Win32_UserAccount -Filter "Name = '$username'" $profile = Get-CimInstance -Class Win32_UserProfile -Filter "SID = '$($user.SID)'" $folder = Split-Path -Path $profile.LocalPath -Leaf if ($folder -eq $username){ Remove-CimInstance -InputObject $profile } else { Write-Warning -Message "Could not resolve profile and user name" } }
I’m going to start with the CIM cmdlets as these are the way of the future in PowerShell v3.
Start by taking a user name as a parameter. Get the Win32_UserAccount class object representing that account. use the SID to find the profile via Win32_UserProfile. Take the profile’s localpath and split it. The last part of the path should match the username – if it does then delete the profile otherwise throw a warning. Deleting the profile does delete the folder under c:\users
If you have to use the WMI cmdlets then its very similar
function remove-profile { param ( [parameter(Mandatory=$true)] [string]$username ) $user = Get-WmiObject -Class Win32_UserAccount -Filter "Name = '$username'" $profile = Get-WmiObject -Class Win32_UserProfile -Filter "SID = '$($user.SID)'" $folder = Split-Path -Path $profile.LocalPath -Leaf if ($folder -eq $username){ Remove-WmiObject -InputObject $profile } else { Write-Warning -Message "Could not resolve profile and user name" } }
Just the name of the cmdlets change.
You can’t use WMI to delete local accounts as explained on page 363 of PowerShell and WMI
If you have profiles generated by AD accounts you’ll need to find the SID from the AD account and use that as the filter for deletion
This post
http://powershell.com/cs/blogs/tips/archive/2012/06/05/checking-size-of-downloads-folder.aspx
go me thinking about the temp folder. Its one of those areas tucked away in your profile that just seems to get left to grow. Time to do something about it.
$testdate = (Get-Date).AddDays(-10) $names = "FXSAPIDebugLogFile.txt", "hsperfdata_Richard" ## assume TMP = TEMP $path = $env:TEMP Get-ChildItem -Path $path -File | where LastWriteTime -lt $testdate | where Name -NotIn $names | Remove-Item -Force #-WhatIf Get-ChildItem -Path $path -Directory | where LastWriteTime -lt $testdate | where Name -NotIn $names | Remove-Item -Force -Recurse #-WhatIf
I decide to use some of the new functionality in PowerShell v3 and separate the file and folder processing so I could play (er experiment) with some of the new parameters in Get-ChildItem
Get-ChildItem [-Attributes <FileAttributes]>] [-Directory] [-File] [-Force] [-Hidden] [-ReadOnly] [-System]
[-UseTransaction] [<CommonParameters>]
These are a separate parameter set which means that -exclude and –include don’t work with them.
So start by creating a date to test against. Anything older than this will be deleted. Define a few names of things that have to be left alone (these will probably be different on your system) and set the path. I’ve assumed that the TEMP and TMP environmental variables point to the same path. if your system is different put the rest of the code into a foreach loop to iterate through the two variables.
Starting with files we get all the files in the root of TEMP. The –File parameter means we only look at files – folders are automatically excluded.
I’ve then used two where statements. Now the obvious comment is that I could combine them but if I do that I have to check each file for its age and then if its name is in my exclusion list. This way I test for age and immediately filter out any file that it is too young. Then I test for name. Doing it this way gives a small performance increase if you have a lot of young files.
I then pass the files to Remove-Item to delete.
The directories are processed in a similar manner except that we use –Directory on Get-ChildItem and add –Recurse to the Remove-Item call so that non-empty folders are removed.
Next move is to make this a scheduled task using the new PowerShell scheduled task cmdlets.
If you haven’t seen them already Microsoft’s ScriptingGuy has kindly published a couple of excerpts from PowerShell in Depth by Don Jones, Jeff Hicks and myself
http://blogs.technet.com/b/heyscriptingguy/archive/2012/06/04/powershell-in-depth-part-1.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2012/06/05/powershell-in-depth-part-2.aspx
Enjoy
