Monday, August 29, 2011

PowerShell and Benford's Law

Was reading through a statistics blog (R) the other day when I read a posting on Benford's law. The definition according to the blog is:

"
Benford's law, also called the first-digit law, states that in lists of numbers from many (but not all) real-life sources of data, the leading digit is distributed in a specific, non-uniform way. According to this law, the first digit is 1 about 30% of the time, and larger digits occur as the leading digit with lower and lower frequency, to the point where 9 as a first digit occurs less than 5% of the time."

The probabilities are distributed as demonstration here.



This seemed counter-intuitive and I wanted to validate it myself. Let's look at the leading digit of all the txt files in one of my directories. Enter PowerShell.....
# Explore Benford's Law 

$array=@()
foreach ($item in (Get-ChildItem -Path p:\ -Filter *.txt -Recurse))
{
$array+= $item.length.toString()[0]
}

$array `
| Group-Object -NoElement `
| Sort-Object count -Descending `
| Format-Table @{label=”#”;expression={$_.Name}},
@{label=”Count”;expression={"{0:%##}" -f $($_.Count/$array.Count)}},
@{label=”Histogram”;expression={“▄” * $_.Count}} -autosize

I consider this a validation, but lets try one another example, this time looking at leading digits on the workingset of the processes on my desktop:

$array=@()       

foreach($a in (Get-Process))
{
$array+= $a.WorkingSet.toString()[0]
}

$array `
| Group-Object -NoElement `
| Sort-Object count -Descending `
| Format-Table @{label=”#”;expression={$_.Name}},
@{label=”Count”;expression={"{0:%##}" -f $($_.Count/$array.Count)}},
@{label=”Histogram”;expression={“▄” * $_.Count}} -autosize

Again, this seems to hold true. Now that I have examples of Benford's law, I feel compelled to try and understand it. Wish me luck!


Thursday, August 25, 2011

Setting user LogonWorkstations and LogonHours in Active Directory

If you find the need to add restrictions to a user in Active Directory, specifically LogonWorkstations and logonHours then the following script will serve as a template.

A few notes:
- We are using the ActiveDirectory module
- We are using a set list of workstations
- We are using a template approach for the logon hours

Import-Module ActiveDirectory -ErrorAction SilentlyContinue  


# Define the list of workstations we want to allow access
$WorkStations = "Workstation1,Workstation2,Workstation3"
$WorkStations+= "Workstation4,Workstation5,Workstation6"
$WorkStations+= "Workstation7,Workstation8,Workstation9"

# Create the logonHours array
[array]$logonHours = (Get-ADUser test010 -Properties logonHours).logonHours

# Iterate over users and assign accordingly
foreach ($user in Get-Content C:\temp\users.txt) {
Get-ADUser -Identity $user |
`
Set-ADUser -LogonWorkstations $Workstations -Add @{logonhours=$logonHours}
}
Checking our results shows that the logonHours were set exactly to what our template was.


Enjoy!