Prof. Powershell

Touch Me, Baby (with Set-ItemProperty, of course)

Here's a way to get beyond the usual looking into file properties and time stamps and start changing them.

Chances are you primarily use Windows PowerShell to look at things like files, services and processes. Of course given the proper credentials you are allowed to touch just about anything. In today's class, I want to show you how to modify file properties such as their attributes and time stamp.

In PowerShell, many things we look at are generically referred to as items. For example, consider Get-ChildItem -- its job is to retrieve all items that are children in the specified or current container. If you know the item name, you can retrieve it with Get-Item:

PS C:\work> get-item foo.txt

   Directory: C:\work

Mode    LastWriteTime      Length   Name
----    -------------      ------   ----
-a---   3/8/2011 7:59 PM   13876    foo.txt

Some items, like files and registry keys, have properties. You can see some of the properties in the output. To see everything you could use the Get-ItemProperty cmdlet:

PS C:\work> get-itemproperty .\foo.txt | select *

To be sure, there are other ways to get the same information but the end result is what matters. Now that I can see some properties, I can change some of them using the Set-ItemProperty cmdlet. See how these things work in pairs? For example, let's say I need to change the file to be read-only and keep the archive flag. I need to specify the item path, the property name and a value:

PS C:\work> set-itemproperty .\foo.txt -Name Attributes -Value "ReadOnly,Archive"

The cmdlet doesn't write to the pipeline unless you use -Passthru, but it made the change:

PS C:\work> get-item .\foo.txt

   Directory: C:\work

Mode   LastWriteTime      Length   Name
----   -------------      ------   ----
-ar--  3/8/2011 7:59 PM   13876    foo.txt

It's not much more work to apply this type of change to multiple files:

PS C:\work> dir *.ps1 | set-itemproperty -Name Attributes -Value "readonly,archive"

I've just set all PowerShell scripts in my Work folder as ReadOnly. This also works on folders:

PS C:\work> set-itemproperty .\secret -name Attributes -Value "Hidden" -PassThru | get-item -force

   Directory: C:\work

Mode   LastWriteTime      Length   Name
----   -------------      ------   ----
d--h-  9/27/2011 9:09 AM           secret

Touching time stamps isn't that much more difficult. I want to leave the creation time alone but update the last write and access times. Here's one approach:

PS C:\work> get-item c:\work\foo.txt | Foreach {
>> $_ | set-itemproperty -Name LastWriteTime -Value "09/10/2011 1:10:00 AM"
>> $_ | set-itemproperty -Name LastAccessTime -Value "09/10/2011 1:10:00 AM" -passthru
>> } | get-item | select Name,Last*
>>

Name              : foo.txt
LastAccessTime    : 9/10/2011 1:10:00 AM
LastAccessTimeUtc : 9/10/2011 5:10:00 AM
LastWriteTime     : 9/10/2011 1:10:00 AM

The UTC times will automatically be updated accordingly.

The next time you feel the need to get all touchy-feely, be sure to look at full help and examples for Set-ItemProperty.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular