Adding a pause to you Powershell scripts

If you have taken a look at some of the scripts I have posted earlier you might have noticed a rather strange line, usually at the end of the script:

cmd /c pause | out-null

This was actually just to get the script to wait for the user to press a key. It is equivalent to the good ol’ pause in batch scripting.
The reason I used this method was that I just didn’t know how to do this in Powershell (yes, I am ashamed). But now I have stumbled upon the Powershell way to do it:

$null = $host.ui.rawui.readkey("NoEcho,Includekeydown")

This will do exactly the same as pause in batch scripting Smilie: :)

Posted in Microsoft, Powershell Tagged ,

Powershell function for rotating event logs

A friend of mine came to me with an interesting powershell challenge today: how can I use powershell to archive and clear event logs?

Well, challenge accepted!

The reason the challenge arose is due to maintenance he performs on a number of customer servers. Every month he saves each eventlog and clears it manually, a time consuming task if you have more than a few servers.

So here’s what I came up with:
A powershell function, Rotate-EventLogs, that exports the application, system and security logs to xml files with todays date as filename, then the logs are cleared.

The function isn’t really all that advanced, it checks if the folders where the logs will be saved exists, if not it will create them.
Then it will export each log to c:eventlogs<logname>%d%m%Y.xml For example the system log exported today would be located at c:eventlogssystem6092012.xml.
After the export of the three eventlogs it will clear them.

What he will have to do manually is to add the function code to %windir%system32WindowsPowerShellv1.0profile.ps1 on each server.

He can then set up a scheduled task that only runs Rotate-Eventlogs in a powershell window every month.

Challenge completed!

Here’s the code for the function:

function Rotate-EventLogs
{
$today = get-date -UFormat %d%m%Y

if ((Test-Path c:eventlogs) -eq $False)
{
New-Item c:eventlogs -type directory
}

if ((Test-Path c:eventlogssystem) -eq $False)
{
New-Item c:eventlogssystem -type directory
}

if ((Test-Path c:eventlogsapplication) -eq $False)
{
New-Item c:eventlogsapplication -type directory
}

if ((Test-Path c:eventlogssecurity) -eq $False)
{
New-Item c:eventlogssecurity -type directory
}

Get-EventLog system | export-clixml c:eventlogssystem$today.xml
Get-EventLog application | export-clixml c:eventlogsapplication$today.xml
Get-EventLog security | export-clixml c:eventlogssecurity$today.xml

Clear-EventLog system,application,security

}

Have fun with it if you want. If not, don’t Smilie: :)

UPDATE: If you want to do this remotely you can take a look at this file: https://dl.dropbox.com/u/33041052/bloggting/scriptstuff/powershell/function/rotate-eventlogs_espen_style.ps1
It adds the capability to do it on a remote server, see the help section of the function

Posted in Microsoft, Powershell Tagged , , , ,

“The given Key was not present in the dictionary” error when running Group Policy Modeling

I ran into a rather strange error today when trying to run Group Policy Modeling on a user. Instead of showing me Summary and Settings I received an error stating that The given Key was not present in the dictionary.

At first I thought that maybe we had used some Norwegian characters somewhere in a policy, but after some googling it turns out that this is caused by ticking the parent registry container when using the Registry Wizard to create a gpo registry preference.

Microsoft has published a kb article about it here: http://support.microsoft.com/kb/2692409

However the resolution they are presenting is useless for most organizations I think. Recreating all registry collections is not an option, at least it wasn’t for us.

So here’s how to do it in a less time consuming manor (but it may still take some time):

Edit any gpo you have used to set registry settings, navigate to the registry settings and look for entries looking like this:

The setting you need to delete here is TimeZoneInformation, you can spot them by the icon (the regedit icon) and by the fact that they have a blank Type.

After deleting all of this type of entries you can rerun your query and it will work as it should

Posted in Active Directory, Microsoft Tagged , , , ,

Cisco escape sequence

I better write this down before I forget it again: ctrl+shift+6 x

If this makes absolutely no sense to you I will explain:
When you run commands like traceroute, ping and others within Cisco IOS you can abort them. But you can’t use the usual ctrl+c (that would be to logical I guess), you need to press ctrl+shift+6 and THEN press x.

There’s probably a good explanation for this, but I still feel that it is horribly cumbersome. Especially since I don’t use it that often, so I forget it from time to time Smilie: :P

Posted in Cisco, Network Tagged ,

Function for locating an email address

Yesterday I was given a relatively easy task: find out who or what has a given email address.

As this was within our own Exchange organization it proved to be quite simple:

You can achieve the goal with a simple one-liner:

get-recipient -ResultSize unlimited | where {$_.emailaddresses -match "email@address.com"}

But wouldn’t it be easier to have it in a function? In Powershell, creating functions isn’t all that hard. Basically all you need to do is wrap the command or script block with a function statement, see here:

function Get-EmailAddress ($emailaddress)
{
Get-Recipient -ResultSize unlimited | where {$_.emailaddresses -match "$emailaddress"}
}

See how easy that was?
First you tell powershell that you want to configure a function, then the command you want to associate the function with. Within the ( ) you define what parameters the function will need. Then there’s only a { to start defining what the function will do and a } to end the function.

Now all you have to do in order to find out who or what has a given email address is:

Get-EmailAddress somone@company.com

That will tell you what object has the email address and what kind of object it is (UserMailbox, PublicFolder etc.)

Posted in Exchange, Microsoft, Powershell Tagged , , ,

Function for adding photo in Active Directory

I have always been careful to avoid the really advanced and cool stuff in Powershell, like functions, arrays and such.

But as I created the last script it hit me that it would be really cool to have it in a command, like set-adphoto. After some googling I found that funtions aren’t hard at all!

Basically all I really had to do with the ad photo import script was to add “function Set-ADPhoto { ” in front of the script and end it with a }

But since I already was at it I decided to to a little more, I added some argument handling and a little help file.

Here is the result:

function Set-ADPhoto ($user,$photopath) {
Import-Module active*

$error = "The file is bigger than 12KB. Shrink it or choose another file"
$file = Get-Item "$photopath"
$filesize = $file.length/1KB



if ($filesize -gt 12)
    {
    Write-Host $error
        }
else {
    $photo = [byte[]](get-content $file -Encoding byte)
    Set-ADUser $user -Replace @{thumbnailPhoto=$photo}
        }
<#
.SYNOPSIS 
This function will add a photo to a users Active Directory user object. It also verifies that the file is less than 12KB
.DESCRIPTION 
This funtion checks the filesize of the file given. If it is too big it will output an error message. 
If the file is less than 12KB it will add the given file to the given users thumbnailPhoto attribute in Active Directory
.EXAMPLE 
Set-ADPhoto username p:photo.jpg
Will set the thumbnailPhoto attribute for the user username to the content of p:photo.jpg
.NOTES 
.LINK
http://cloud.kemta.net/2012/08/function-for-adding-photo-in-active-directory
#>
}

 

Posted in Active Directory, Microsoft, Powershell Tagged , , ,

Simple script for adding user photo in Active Directory

It’s been a while since I posted here so I thought it might be time to add some content.

This script is a simple script that adds a photo to a user’s active directory user object. It also checks the filesize to prevent users adding large photos (you can of course change this limit).

The requirements for this script is the Active Directory module and permission to edit a user object in Active Directory

The script:

#Imports the Active Directory module
Import-Module active*

#Asks the user for a filename
$photopath = Read-Host "Please input filepath and filename"

#Converts the users input to an object
$file = Get-Item "$photopath"

#Calculates the filesize
$filesize = $file.length/1KB

#If the file is largers than 12KB you get a message stating that the file is too large
#If the file is smaller than 12KB it asks for a username and imports the file to Active Directory
if ($filesize -gt 12)
{
Write-Host "Filesize to large, shrink it to under 12KB and try again"
}
else {
$user = Read-Host "Please input username"
$photo = [byte[]](get-content $file -Encoding byte)
Set-ADUser $user -Replace @{thumbnailPhoto=$photo}
Write-host "All done"
}

cmd /c pause | out-null

Posted in Active Directory, Microsoft, Powershell Tagged , ,

Check if DAG databases is on preferred server

If you are using DAG in exchange 2010 for high availability on your mailboxes there may be one thing you might have noticed, the databases can fail over to a less preferred server at any time without you noticing.
Microsoft have provided you with a script for balancing these databases, RedistributeActiveDatabases.ps1. With this script you can activate the databases on their preferred server again. But how do you know when they have failed over?

That has been an issue for us for some time now. None of our monitoring solutions were able to detect this, so I decided to write a simple powershell script for this.

The script uses the RedistributeActiveDatabases.ps1 script to check how many, if any, databases is mounted on a less preferred server. If more than 0 databases is mounted on a less preferred server it sends a mail to a given mail address with how many databases is on a less preferred server.

We run this script as a scheduled task on one of our hub transport servers, but you can run it on any server/computer that has exchange management tools installed. It has really helped us so far, so heres the script:

#Add the needed exchange snapin
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

#Navigate to the exchange script repository
cd "CSmilie: :Program FilesMicrosoftExchange ServerV14Scripts"

#Gather info on how many databases is on a less preferred server
$result = .RedistributeActiveDatabases.ps1 -dagname dag01 -ShowDatabaseCurrentActives

#Turn the results into a number
$count = $result | Select-Object IsOnMostPreferredCopy | Select-String False | Measure-Object

#Turn the number into a format that fits nicely into the mail (only for looks Smilie: :))
$body = $count.count | out-string

#Sends mail if there is databases that are mounted on less preferred server
if ($count.Count -gt 0)
{send-mailmessage -smtpserver 'hub transport server' -to some@recipient.com,some.other@recipient -from some@mailaddress.com -subject "DAG unbalanced" -Body "The following number of databases is not on their prefered server: $body"}

Posted in Exchange, Microsoft, Powershell Tagged , , ,

Redirecting a webpage using html

The redirect function in IIS 7 and 7.5 is in my experience pretty buggy. More often than not it will send the visitor into an eternal redirect loop.

Because of that I have used this simple html code for redirecting, instead of using the built in function in IIS.

Use it at your own will, I’m just posting it so I know where to find it the next time I need it Smilie: :)



 Some title
 
 
 
 You are now beeing forwarded to https://some.domain>
If you are not forwarded automatically, click the above link.

Posted in Web code Tagged , ,

Grep’ing the eventlog using powershell

If you are used to working with Linux you’re probably familiar with using tail, grep and such for gathering stuff from logs and other files. Those are quite useful tools and work very well when you want to find out e.g. why a user fails to log in.

In Windows it’s a little different, if we want to find something in the event logs we have always had to resort to a console.
But with powershell you can search through the event logs from a command line:

Get-EventLog is quite the useful cmdlet. You can specify which log you want to search, a time window, usernames, entrytypes and even computername.

If you are a little more experienced with powershell you can even dig down further by piping the command to a where-object cmdlet, for example if you want to see all entries in the system log with the event id 7036 you would type:

Get-EventLog -LogName System | Where-Object {$_.EventID -eq 7036}

You probably end up with a long list, so to just show the last 5 entries:

Get-EventLog -LogName System -Newest 5 | Where-Object {$_.EventID -eq 7036}

Note that this will only grab the last 5 entries from the system event log, not necessarily the last 5 entries with event id 7036. So it might be better to use the After parameter to get events since yesterday:

$yesterday = get-date 19/02/12
 Get-EventLog -LogName System -After $yesterday | Where-Object {$_.EventID -eq 7036}

As you can see I define a variable for yesterday, thats just because I’m lazy and want to keep the commands as little complex as I can.

One of the things I commonly use get-eventlog for is figuring out why a user fails to log in through one of our radius servers. Heres one example of a command I would use for that:

$yesterday = get-date 19/02/12
 Get-EventLog -LogName security -computername radiusserver -after $yesterday | Where-Object {$_.entrytype -eq "FailureAudit" -and $_.Message -like "*username*"} | fl

So as you can see, the get-eventlog cmdlet is quite useful, especially when you combine it with where-object. Also remember that you can always output any data you receive to a csv by piping the command: | export-csv c:filname.csv

Posted in Microsoft, Powershell Tagged , ,