Monthly Archives: February 2014

do and while

Do you understand the difference between do loops and while loops?  On the surface they appear very similar.

£> do{$i++}while($i -lt 10)
£> $i
10

£> $i=0
£> while($i -lt 10){$i++}
£> $i
10

BUT there is a difference

£> $i=11
£> do{$i++}while($i -lt 10)
£> $i
12

£> $i=11
£> while($i -lt 10){$i++}
£> $i

Notice the difference in the final result

A DO loop will ALWAYS execute at least once because the test is at the end.

A while loop has the test at the beginning so may not execute at all.

I’ve seen this cause people real difficulty at times so think about where you need the test to be, if the loop needs to execute at least once and what the final value of any incrementing variables should be

Automatically create folder for home drive

In this post  http://richardspowershellblog.wordpress.com/2013/10/28/setting-ad-attributes-from-a-csv-file/

I showed how to modify the user’s home folder setting in Active Directory.

A comment was recently left asking about automatically creating the folder on the fileserver and creating the share that is associated with it.

This isn’t a simple exercise – you will need a script to:

You can create the folder using New-Item

New-Item -Path c:\test -Name anyolduser -Type Directory

You can share it

$max = [uint32]5

$type = [uint32]0

Invoke-CimMethod -ClassName Win32_Share -MethodName Create -Arguments @{Name='anyolduser'; Path='c:\test\anyolduser';
Type=$type; MaximumAllowed=$max; Description='anyolduser - homedrive'}

And then you have to set share and NTFS permissions according to your organization’s policies

File or Folder?

This is a common type of use for Get-ChildItem:

Get-ChildItem -Path c:\temp 

However, you could get files or folders returned.  Very often you just want to see the files

In PowerShell 1.0 & 2.0 you had to do this:

Get-ChildItem -Path c:\temp   | where {-not $_.PSIsContainer}

If you want to see the subfolders only then you reverse the condition:

Get-ChildItem -Path c:\temp  | where {$_.PSIsContainer}

In PowerShell 3.0 Get-ChildItem got some new parameters –File and –Directory. They display files only or folders only respectively. The default action is still to display files and folders.

Get-ChildItem -Path c:\temp  -File
Get-ChildItem -Path c:\temp  -Directory

I still see a lot of people making more work for themselves because they don’t use or don’t know about the new parameters.

I’m afraid you can’t do that anymore

In PowerShell 1.0 you could do this:

notepad
$proc = Get-WmiObject -Class Win32_Process -Filter "Name='notepad.exe'"
$proc.Terminate()

To access the methods of the WMI class you had to get a variable representing the instance and call the method. This technique still works in PowerShell 4.0

When the CIM cmdlets were introduced in PowerShell 3.0 people assumed that they worked the same:

£> notepad
£> $proc = Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'"
£> $proc.Terminate()
Method invocation failed because [Microsoft.Management.Infrastructure.CimInstance] does not contain a method named
'Terminate'.
At line:1 char:1
+ $proc.Terminate()
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Terminate:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

The CIM cmdlets retrun inert objects – NO METHODS – so you can’t do that.

The correct way to use the CIM cmdlets is:

Get-CimInstance -ClassName Win32_Process -Filter "Name='notepad.exe'" | Invoke-CimMethod -MethodName Terminate

Learn AD Management in a Month of Lunches–ebook available

The ebook – PDF format - for Learn AD Management in a Month of Lunches has been published - http://www.manning.com/siddaway3/

If you bought the ebook as part of your MEAP you should be able to down load it – you’ll get or have got an email with the link. The printed version is at the printers and will be available on 12 March.

If you want the ebook in Kindle or epub versiosn they will be available 20 March.

Enjoy.

PowerShell Summit NA 2014–reasons to attend

The PowerShell Summit is happening in Bellevue (Seattle) – April 28 – 30th.  You will be able to hear, meet and talk to some of the biggest names in PowerShell:

- Jeffrey Snover – the inventor of PowerShell

- PowerShell Team members

- Don Jones

- Jason Helmick

- Jeff Hicks

- Ed Wilson (The Scripting Guy)

- Steven Murawski

- Tome Tanasovski

- James O’Neill

I’ll be there delivering 3 sessions (WSMan cmdlets, cmdletizing the registry and using the network related cmdlets) – its the only chance this year of getting all three authors of PowerShell in Depth in the same place at the same time.

If you haven’t booked a place yet – you can register and view the rest of the sessions at http://powershell.org

Useful storage cmdlets

Scanning through the Storage module there is a bunch of useful cmdlets – starting with the Get* cmdlets:

Get-Command -Module Storage get*

Get-Disk
Get-DiskImage
Get-FileIntegrity
Get-FileStorageTier
Get-InitiatorId
Get-InitiatorPort
Get-MaskingSet
Get-OffloadDataTransferSetting
Get-Partition
Get-PartitionSupportedSize
Get-PhysicalDisk
Get-ResiliencySetting
Get-StorageJob
Get-StorageNode
Get-StoragePool
Get-StorageProvider
Get-StorageReliabilityCounter
Get-StorageSetting
Get-StorageSubSystem
Get-StorageTier
Get-StorageTierSupportedSize
Get-SupportedClusterSizes
Get-SupportedFileSystems
Get-TargetPort
Get-TargetPortal
Get-VirtualDisk
Get-VirtualDiskSupportedSize
Get-Volume
Get-VolumeCorruptionCount
Get-VolumeScrubPolicy

£> Get-PhysicalDisk | Format-List FriendlyName, CanPool, OperationalStatus, HealthStatus, Usage, Size


FriendlyName      : PhysicalDisk0
CanPool           : False
OperationalStatus : OK
HealthStatus      : Healthy
Usage             : Auto-Select
Size              : 256060514304

 

£> Get-Disk | ft -a

Number Friendly Name      OperationalStatus Total Size Partition Style
------ -------------      ----------------- ---------- ---------------
0      HFS256G3AMNB-2200A Online             238.47 GB GPT

£> Get-Partition | ft -a


   Disk Number: 0

PartitionNumber DriveLetter Offset            Size Type
--------------- ----------- ------            ---- ----
1                           1048576         350 MB Recovery
2                           368050176       200 MB System
3                           577765376       128 MB Reserved
4               C           711983104    231.85 GB Basic
5                           249663848448   5.96 GB Recovery

£> Get-Volume | ft -a

DriveLetter FileSystemLabel  FileSystem DriveType HealthStatus SizeRemaining      Size
----------- ---------------  ---------- --------- ------------ -------------      ----
C           Windows          NTFS       Fixed     Healthy           160.2 GB 231.85 GB
            Windows RE tools NTFS       Fixed     Healthy           56.86 MB    350 MB
            Recovery image   NTFS       Fixed     Healthy          445.72 MB   5.96 GB

Delete all but the last N

I was asked a question about deleting files from a folder based on age.  The requirement was to delete all but the youngest N files.

One solution is a classic PowerShell one-liner. It is actually one PowerShell pipeline though I’ve split it across multiple lines for ease of reading.

Get-ChildItem -Path c:\temp -Filter *.tmp -File |
sort LastWriteTime -Descending |
select -Skip 5 |
Remove-Item

Use Get-Childitem to read the files you’re interested in. I’ve used the –File parameetr to restrict the examination to files.

Sort the files on LastWriteTime – you could use CreationTime if the files haven’t been changed since creation. You want the results sorted in descending order so the latest files are at the top of the list. Younger dates are greater than older dates.

use Select-Object to skip the first N (in this case 5) files and pipe everything else into remove-item.  Add a –whatif parameter to Remove-Item if want to see how its working before letting it loose.

A nice simple answer with a use for Select-Object’s –Skip parameter that I hadn’t thought of before.

Requires

You may have seen this at the top of scripts or modules

#Requires –Version 3

 

This will stop the script running if the PowerShell version is 2.0 or below.

Other options are available

 

#Requires –PSSnapin      can be used to force the loading of a snapin

 

#Requires –Modules     can be used to force importing of modules

 

#Requires –Shellid    controls which shells the script can run in.  Default PowerShell installs have the ISE and console

 

#Requires –RunAsAdminstrator  - script must be running in instance of PowerShell with elevated privileges

 

These provide a simple and easy way to control execution without lots of code. I particularly like the last one.

Waiting for restart

Some times you need to reboot a remote machine as part of your process.  PowerShell provides the Restart-Computer cmdlet to perform that task:

Restart-Computer -ComputerName server03

If you want you process to pause until the reboot has finished then you add the –Wait parameter:

Restart-Computer -ComputerName server03

You final options when pausing are to wait until a specific service – PowerShell, WinRM or WMI is avialable:

Restart-Computer -ComputerName server03 -Wait -For PowerShell

Restart-Computer -ComputerName server03 -Wait -For WinRM

Restart-Computer -ComputerName server03 -Wait -For Wmi

These options should cover most situations as these services are among the last to become available when a machine starts.