PowerShell for Windows Admins


June 25, 2013  1:43 PM

UK PowerShell group



Posted by: Richard Siddaway
PowerShell, User Group

As you are probably aware the UK PowerShell group has been very quiet over the last few months. This has been due to my personal circumstances – hopefully now resolved.

I want to re-start the group and was wondering what people wanted.

When I started the group 6 years ago we were the only PowerShell user group in the world! Things have changed. Back then I could easily organise physical meetings where the personal contact and ability to talk to people who were also learning PowerShell was invaluable. Its not possible to get the venues these days so I switched to using Live Meeting. Not as satisfying but much easier from a logistics stand point. There are problems with sound quality over Live Meeting. I’ve tried it on a number of networks from a number of machines and the sound is poor at best and impossible to listen to at worst.

The big problem for any user group is finding speakers. There aren’t that many people willing to speak on any particular topic and many of them aren’t based in the UK.

At the moment I’m thinking of a web cast every other month. I can’t do every month – I just don’t have the time. If I can find other speakers to fill the gaps that will be great but I’m working on worst case. Six sessions a year I can manage.

This supposes that I can resolve the sound problems. I’m experimenting with Lync and hope that will solve the problem. if it doesn’t then a total rethink is required.

So the question to the PowerShell community – what do you want?

June 25, 2013  12:46 PM

The inverse association



Posted by: Richard Siddaway
PowerShell, PowerShell 3, WMI

In my last post I showed how to find the groups of which a local user is a member. A comment was left asking about the inverse relationship.

In this case we can just turn the code round.

Get-CimInstance -ClassName Win32_Group |
foreach {
$users = Get-CimAssociatedInstance -InputObject $psitem `
-ResultClassName Win32_UserAccount |
select -ExpandProperty Caption

$psitem | Add-Member -MemberType NoteProperty -Name ‘Users’ `
-Value ($users -join “;”) -PassThru

} | select Name, Users

Note: You can’t do this as a matter of course with all WMI relationships. Some relationships are one way in that A has a link to B but B has no way to link back to A unless you can find a property in common.


June 24, 2013  3:23 PM

WMI association example



Posted by: Richard Siddaway
PowerShell, PowerShell 3, WMI

A question came up on the Powershell.org forum about finding the groups of which local accounts are members

You can get account data using Win32_UserAccount

Group information is held in Win32_Group. You can see the relationship between users and groups by dumping the Win32_GroupUser instances. You will see a load of entries like this

GroupComponent : Win32_Group (Name = “Administrators”, Domain = “RSLAPTOP01″)
PartComponent : Win32_UserAccount (Name = “Administrator”, Domain = “RSLAPTOP01″)
PSComputerName : CimClass : root/cimv2:Win32_GroupUser
CimInstanceProperties : {GroupComponent, PartComponent}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

WMI classes have associations – in this case there is an association between the Win32_User and the Win32_Group classes. The Win32_GroupUser can be thought of as the linking class. What we need to do to is to go from the individual instances of Win32_User (the users) to the associated groups.

Something like this should do it

$data = Get-CimInstance -ClassName Win32_UserAccount -Filter “LocalAccount = $true” |
foreach {
$groups = Get-CimAssociatedInstance -InputObject $PSItem -ResultClassName Win32_Group | select -ExpandProperty Name
$PSItem | Add-Member -MemberType NoteProperty -Name “Groups” -Value ($groups -join “;”) -PassThru
}
$data | select Caption, Groups

WMI – a bit convoluted but it always gets there


June 24, 2013  12:04 PM

Touching files



Posted by: Richard Siddaway
File System, PowerShell

Unix has a command called touch that allows you to set the access time on a file. PowerShell doesn’t have a direct equivalent but it is very easy to perform the same task:

$date = (Get-Date).AddMonths(-2)
Get-ChildItem -Path C:\Teszzt2 -Filter f*.txt |
Set-ItemProperty -Name LastWriteTime -Value $date -PassThru |
Set-ItemProperty -Name LastAccessTime -Value $date -PassThru |
Set-ItemProperty -Name CreationTime -Value $date

Set the date you want. Get the files and pipe into Set-ItemProperty. The example shows LastWriteTime, LastAccessTime and CreationTime all being modified. Change the code to just change what you need.

You can see the results

Get-ChildItem -Path C:\Teszzt2 -Filter f*.txt |
select Name, LastAccessTime, LastWriteTime, CreationTime


June 23, 2013  3:15 PM

PowerShell.org newsletter



Posted by: Richard Siddaway
PowerShell

At powershell.org we publish a monthly email newsletter. As well as PowerShell related news you get a feature article. These articles are only published through the newsletter and are written by acknowledged PowerShell experts.

You can subscribe, for free, at

http://powershell.org/wp/newsletter/


June 23, 2013  8:21 AM

Clearing Event logs



Posted by: Richard Siddaway
Operating System, PowerShell

I needed to clear some event logs on a test machine. Rather than picking and choosing I’ll clear them all

Get-EventLog -List |
where {($_.Entries).Count -gt 0} |
foreach {Clear-EventLog -LogName $_.Log}

The interesting part is the where-object filter in that Entries is a collection of the Entries in the log. If you want the number of entries you have to specificaly ask for it. The output of get-eventlog –list is formatted to display the count


June 23, 2013  5:57 AM

Opinion–automate or suffer



Posted by: Richard Siddaway
Opinion

I was on a course last week and one attendee uttered words to this affect “I won’t automate – it takes to long to write the code. I’ll keep doing it manually”

You may be able to do it faster the first time by performing the task manually. I can guarantee that the second time my automation will be faster and by the third time I’ll have recovered the effort I made in automating.

IT is getting more complicated, with more dependencies and less time to set things up. If you want consistent, quick results – automate. if you don’t – you’re in the wrong business.


June 12, 2013  3:31 PM

Scripting Games – what’s wrong with this



Posted by: Richard Siddaway
PowerShell, Scripting Games

I noticed code like this in quite a few entries in for Event 1

Get-ChildItem -path C:\Application\log -Recurse -Filter *.log | Where-Object{$_.LastWriteTime -lt [DateTime]::Now.Subtract([TimeSpan]::FromDays(90))} | ForEach-Object {…}

From the title it should be obvious that there’s something I don’t like.

The where-object re-calculates the date to test for EVERY object on the pipeline.

That’s not efficient.

Put the calculation outside your pipeline

$testdate = [DateTime]::Now.Subtract([TimeSpan]::FromDays(90))

or

$testdate = (get-date).AddDays(-90)

which I personally think is simpler

Your pipeline then becomes

Get-ChildItem -path C:\Application\log -Recurse -Filter *.log | Where-Object{$_.LastWriteTime –lt $testdate} | ForEach-Object {…}

Much simpler and more efficient.

I wonder if putting the calculation into the pipeline is part of the almost religious fervour surrounding the “one-liner”. if you can sensibly put your code into 1 line – read one pipeline because that’s what we’re really doing – then do so. But don’t make it more inefficient as a consequence.


June 10, 2013  3:13 PM

AD Management in a Month of Lunches–new MEAP



Posted by: Richard Siddaway
Active Directory, Books, PowerShell 3

Chapters 12 and 13 have been added to the Manning Early Access Program

Chapter 12 shows you how to manage your domain controllers

Chapter 13 teaches how to protect the data in your Active Directory

You can order the MEAP from www.manning.com/siddaway3


June 8, 2013  5:49 AM

Creating DNS PTR records



Posted by: Richard Siddaway
CIM, DNS, PowerShell 3, PowerShell v2, WMI

When I was writing the DNS chapter of PowerShell in Practice I couldn’t get the CreateInstanceFromPropertyData method on the MicrosoftDNS_PTRType class to work. Revisiting DNS for AD management in a Month of lunches this time round I have access to the CIM cmdlets so can put the parameter names in. This gives usage like this. I’ve shown Invoke-WmiMethod and Invoke-CimMethod so you can see the parameter names:

Invoke-WmiMethod -Namespace root\MicrosoftDNS -Class MicrosoftDNS_PTRType `
-Name CreateInstanceFromPropertyData `
-ArgumentList “175.168.192.in-addr.arpa”, ‘server02′, ’55.175.168.192.in-addr.arpa’,
“ADMLServer02.admldns.test”

Invoke-CimMethod -Namespace root\MicrosoftDNS -ClassName MicrosoftDNS_PTRType `
-MethodName CreateInstanceFromPropertyData `
-Arguments @{Containername = “175.168.192.in-addr.arpa”;
DnsServerName = ‘server02′; OwnerName = ’55.175.168.192.in-addr.arpa’;
PTRDomainName =”ADMLServer02.admldns.test”}

If you have access to Windows 2012 then you are better off using the cmdlet

Add-DnsServerResourceRecordPtr –Name ‘54’ `
–ZoneName “175.168.192.in-addr.arpa” `
–PtrDomainName ‘ADMLServer01.admldns.test’ `
–ComputerName server02

Which ever method you use – you can easily create PTR records


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: