Friday, 30 September 2016

Get Last Windows Operating System Boot Time using Powershell

We can easily use powershell to query a computer to retrieve the time and date that windows last booted/started up.

We run a get-wmiobject query to retrieve the properties from the win32_operatingsystem class and store the results into the $osprops variable. We then run to ConvertToDateTime method on the LastBootUpTime property to return the result and store it in the $lastboot variable

$osprops = get-wmiobject -class win32_operatingsystem 
$lastboot = $osprops.ConvertToDateTime($osprops.LastBootUpTime)

The $lastboot variable will then provide an output like below;



This variable can be parsed through different methods to change the output to a different format. you can view all the different methods available by running $lastboot | get-member

Some examples.

$lastboot.ToShortDateString() will return the above date in the format of mm/dd/yyyy
$lastboot.DayOfWeek will only return the day of the week (eg. Monday, Tuesday, etc)

Thursday, 29 September 2016

iPhone/iPad - Cannot send mail. A copy has been placed in your Outbox. The recipient was rejected by the server

Occasionally I've seen users experience an issue where they can no longer send emails to anyone from their iPad or iPhone, they get the below error message;

"Cannot send mail. A copy has been placed in your Outbox. The recipient %name% was rejected by the server"

The issue is usually caused by the authentication (ie. username and password) failing for the email account, because it is either missing or incorrect.

I've often seen this happen after iOS updates, as passwords for email accounts aren't always preserved during the update process. As a result, the password appears to be present (when you check the settings), but actually isn't, and therefore emails won't send any longer.

To fix the issue, do the following on the problematic device(s);


  • Go to Settings
  • Go to Mail

  • Select Accounts

  • Select the account that you are having problems sending from

  • Select the account again (first option at top of screen)

  • Update the Domain, Username and Password fields. Even if the password appears to be in there (represented by black circles), delete whatever is in there and re-type the password

  • Click Done from the top right corner. Settings should now be checked and you should get a list of ticks down the ride side of the page
If the settings saved successfully you can try sending emails again, it should now work correctly.

Wednesday, 28 September 2016

Querying/Checking Windows Logical Disks using Powershell

Below is a script you can use to check/query windows logical disks using powershell. This can be useful to regularly check the free space on logical drives on a windows server or PC.

$diskreport = Get-WmiObject Win32_logicaldisk | Select DeviceID, MediaType, VolumeName, `
    @{Name="Size(GB)";Expression={[decimal]("{0:N0}" -f($_.size/1gb))}}, `
    @{Name="Free Space(GB)";Expression={[decimal]("{0:N0}" -f($_.freespace/1gb))}}, `
    @{Name="Free (%)";Expression={"{0,6:P0}" -f(($_.freespace/1gb) / ($_.size/1gb))}}

The script uses the get-wmiobject cmdlet to query the logical disks configured within windows. The results are then compiled into the $diskreport variable so they can then be further queried or exported to a .csv file.

Free space as a percentage is also calculated automatically as part of this script.

A sample output from the $diskreport variable is below (A:\ and D:\ are the floppy drive and DVD drive with no media loaded which is why they've returned values of 0)

Tuesday, 27 September 2016

Querying/Checking Windows Event Viewer Logs with Powershell

Powershell has a cmdlet you can use to check/query the windows event log.  You can customize this cmdlet in several ways to refine the information that is returned.

For example, you can use the -after switch to only return event log entries after a certain date - such as events only returned within the past 1 day (24 hours)

You can also filter the type of entries that are returned. An example would be to only return warning or error entries, and ignore any "informational" type entries

Let's start with the basic command;

get-eventlog -logname "Application"

This command will return all entries within the Application log, which will usually be alot, and not very useful. You can also use "System" or "Security" as other default logs.

Let's refine the command further, to only return entries for the past day. To do this we will define the current date into the $date variable, and subtract one day from that value

$date = get-date
$date = $date.adddays(-1)

We can now use this $date variable to return all event log entries AFTER this date (using the -after switch)

get-eventlog -logname "Application" -after $date

The script will now return ALL events from the Application log from the past 24 hours. Let's refine it a bit further and filter the results so only Warning and Errors are returned

get-eventlog -logname "Application" -after $date | where-object {$_.entrytype -ne "Information"}

Of course you can store the results into a variable so it can be further queried using subsequent commands;

$events = get-eventlog -logname "Application" -after $date | where-object {$_.entrytype -ne "Information"}

Monday, 26 September 2016

Active Directory User Account Audit including Status with Powershell

Here is a script I have created that searches for all users within an Active Directory domain and provides a report (.csv file) showing all account names and their status. The status is determined from the useraccountcontrol property contained within each account.

The useraccountcontrol property is stored as a number/integer - the most common numbers/values I've translated to their meanings as part of this script - eg. Enabled, Disabled, Password Expired etc.

You only need to change the value for $outfile variable if required - the script should work in it's current form on any windows/active directory domain

$report = @()
$outfile = "C:\temp\UserAudit.csv"

$searcher = New-Object DirectoryServices.DirectorySearcher 
$searcher.filter = "(&(objectCategory=person)(objectClass=user))"

$userlist =  $searcher.FindAll()

foreach ($user in $userlist)
    {
    $name = $($user.properties.displayname)
    $dn = $($user.properties.distinguishedname)
    $status = $($user.properties.useraccountcontrol)
        if ($status -eq "66050"){$status = "Disabled, password never expires"}
        elseif ($status -eq "66048"){$status = "Enabled, password never expires"}
        elseif ($status -eq "512"){$status = "Enabled Account"}
        elseif ($status -eq "514"){$status = "Disabled Account"}
        elseif ($status -eq "66080"){$status = "Enabled, password never expires, user cannot change password"}
    
    $report += new-object psobject -property @{Name=$name;DN=$dn;Status=$status}
    }
    
$report | select Name, Status, DN | export-csv -path $outfile -notype

The script could be further customized to include other values/properties from the account as required. In it's current form it includes the users display name, distinguished name and status.

Friday, 23 September 2016

How to easily view/find the distinguished name for an Active Directory user account

The distinguished name for a user account is often required for scripting or other management/administrative tasks when working with Active Directory. It represents the unique identifier for every user account so is one of the best ways to work with user accounts (as opposed to just working off first name, last name etc).

They are difficult to remember, and nearly impossible to type using the correct format/syntax - so here's some simple instructions on how to quickly/easily obtain the distinguished name for a user account from Active Directory Users & Computers;

  1. Open Active Directory Users & Computers
  2. Ensure "Advanced Features" are enabled (go to View > Advanced Features)
  3. Open the Active Directroy User object you wish to view the DN for
  4. Select the Attribute Editor tab
  5. Scroll down to the locate the Distinguished Name value
  6. You can double click the entry then copy it to the clipboard from the "Value" field as per the screenshot below

Thursday, 22 September 2016

Copy Active Directory User Group Memberships to Another User with Powershell

I have developed the below script to allow you to easily copy Active Directory user group memberships from one user to another. This can be handy if a user is a member of a large number of groups and you don't wish to manually copy them over.

This script is also beneficial in that it doesn't require the Active Directory modules to be installed in powershell for it to work.

In order for the script to work, you will first need to know the distinguished name (DN) for both the source and target user accounts. This can be easily obtained from Active Directory Users & Computers using the steps below;


  1. Open Active Directory Users & Computers
  2. Ensure "Advanced Features" are enabled (go to View > Advanced Features)
  3. Open the Active Directroy User object you wish to view the DN for
  4. Select the Attribute Editor tab
  5. Scroll down to the locate the Distinguished Name value
  6. You can double click the entry then copy it to the clipboard from the "Value" field as per the screenshot below

Once you have the source and target user distinguished names, replace the values for the $srcuserdn and $dstuserdn variables. Be sure to leave the quotes ("") in place

$srcuserdn = "CN=Mike,CN=Users,DC=morrissey,DC=local"
$dstuserdn = "CN=Peter,CN=Users,DC=morrissey,DC=local"
$dstuserldap = "LDAP://$dstuserdn"

$grouplist = dsquery user $srcuserdn | dsget user -memberof

foreach ($group in $grouplist)
    {
    if ($group)
        {
        $group = $group.substring(1,$group.length-2)
        $ldapcon = "LDAP://$group"
        $ldapgroup = [ADSI] $ldapcon
        $ldapgroup.add($dstuserldap)
        }
    }