Showing posts with label audit. Show all posts
Showing posts with label audit. Show all posts

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)

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)

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, 16 September 2016

Export/Audit All Exchange ActiveSync Devices using Powershell

Below are a couple of commands we can use in Windows Powershell to run a report on all mobile devices that have been synced with mailboxes within your exchange environment.

First step is to gather a list of users that have an ActiveSync Device partnership

$userlist = gt-casmailbox -filter {hasactivesyncdevicepartnership -eq $true -and -not displayname -like "CAS_{*"} | Get-Mailbox

This list of users is then used against the Get-ActiveSyncDeviceStatistics cmdlet to retrieve the associated ActiveSync devices with each users mailbox. We then select certain fields to reduce the amount of data and present it in the $report variable.

$report = $UserList | foreach { Get-ActiveSyncDeviceStatistics -Mailbox $_} | select Identity, LastSuccessSync, DeviceType, Status

You can also add the export-csv component onto the end of the command to export the $report contents to a .csv file

$report = $UserList | foreach { Get-ActiveSyncDeviceStatistics -Mailbox $_} | select Identity, LastSuccessSync, DeviceType, Status | export-csv -path "C:\ActiveSyncDevices.csv" -notype

Wednesday, 14 September 2016

Check which Exchange Mailboxes a User has Full Access or Send As Permissions On using Powershell

As an exchange administrator, you may occassionally need to know which mailboxes a particular user has Full Mailbox Access or Send As permissions to. This may be required as part of an audit, or to simply copy an existing users permissions for a new user you are setting up/creating.

The script below helps to accomplish this, as there is no in-built/easy way to view which mailboxes a particular user has access to - ie. Full Mailbox Access, or Send As permissions

First you need to specify the user whose existing access we are checking, using the $user variable. We use the wildcard "*" to essentially match any name that contains what is between the *'s - the users first name, last name or alias should work.

$user = "*peter*"

Next we run the get-mailbox cmdlet against all mailboxes in exchange, to query the permissions on each mailbox to see if this user exists in the respective permissions list.

There are two separate commands to do this - one to check for Full Access permissions, and the other to check for Send As permissions

get-mailbox -resultsize unlimited | get-mailboxpermission | where {$_.user -like $user} | select Identity, AccessRights

get-mailbox -resultsize unlimited | get-adpermission | where {($_.user -like $user) -and ($_.ExtendedRights -like "*Send-As*")} | select Identity, ExtendedRights

If any matches are found, the results will be displayed showing their Identity (ie. name) and the Access Rights level they have

Tuesday, 13 September 2016

Export All Exchange Mailbox Sizes with Powershell

Here is a script you can run on your exchange server to export a list of all mailboxes on the server and the size of each mailbox. This is useful for checking/monitoring mailbox size and usage.

First of all we need to get the name of the mailbox database to query

$mbdb = get-mailboxdatabase | select Name

Next, we use this database name in the get-mailboxstatistics cmdlet to query all mailboxes within the database and export the size from the TotalItemSize field. The list is then sorted alphabetically by display name and exported to a .csv file so it's easier to view

get-mailboxstatistics -database "$($dbname.name)" | select DisplayName, TotalItemSize | sort DisplayName | export-csv "C:\1GB-MailboxList.csv" -notype

You can also implement a "filter" of sorts so that you only export mailboxes that are bigger than a certain size. For example, you may want to know how many mailboxes you have that are larger than 1GB. To do this, we add a filter using the "where {$_.totalitemsize -ge $size}" where $size is the size value you need, in bytes.

So for the example of 1GB, the $size variable would be set to 1073741824 which is 1GB in bytes.

There is a handy utility you can use by following the link below to quickly convert the size you require from GB to bytes

http://www.convertunits.com/from/GB/to/byte

$size = "1073741824"

get-mailboxstatistics -database "$($dbname.name)" | where {$_.totalitemsize -ge $size} | select DisplayName, TotalItemSize | sort DisplayName | export-csv "C:\1GB-MailboxList.csv" -notype

Friday, 9 September 2016

Get ActiveSync Enabled Accounts/Mailboxes using Powershell

Here is a short/simple script you can use to obtain a list of all mailboxes within your Exchange environment that have the ActiveSync service enabled on them.

#Add Exchange Cmdlets
add-pssnapin *exchange* -erroraction SilentlyContinue

get-casmailbox -resultsize unlimited | where {$_.ActiveSyncEnabled -eq $true}

The output will now be displayed showing all mailboxes in your environment that have ActiveSync functionality enabled on them.

You can export your results to a .csv by adding a bit more to the end of the command as per below. You can of course change the output path as required

get-casmailbox -resultsize unlimited | where {$_.ActiveSyncEnabled -eq $true} | select Name, ActiveSyncEnabled | export-csv "C:\activesyncusers.csv" -notype

Friday, 28 March 2014

Check/Monitor Website URL with Powershell

Windows Powershell has a built in web request module that you can use to test/check the availability of website URL(s).

The full script to do this is below;

[string] $url = "http://www.google.com"
[net.httpWebRequest] $req = [net.webRequest]::create($url)
$req.method = "HEAD"
[net.httpWebResponse] $res = $req.getresponse()

The first line is self explanatory - simply put in the full URL for the website you wish to check. In this example we will be checking http://www.google.com

[string] $url = "http://www.google.com"

The second line is where we create the actual web request instance in Powershell - under the $req variable

[net.httpWebRequest] $req = [net.webRequest]::create($url)

On the third line, we change the request method to be "HEAD" which means that only header information for the requested URL is retrieved. This speeds up the web request process as it does not pull all the data from the web URL - only the header information. If you leave this line out, the default method is "GET".

$req.method = "HEAD"

On the last line we actually submit the web request, and store the response in the $res variable

[net.httpWebResponse] $res = $req.getresponse()

For a successful web request, the response should look something like this:

IsMutuallyAuthenticated : False
Cookies                 : {}
Headers                 : {Cache-Control, Content-Type, Date, Expires...}
ContentLength           : -1
ContentEncoding         : 
ContentType             : text/html; charset=ISO-8859-1
CharacterSet            : ISO-8859-1
Server                  : gws
LastModified            : 28/03/2014 10:24:19 AM
StatusCode              : OK
StatusDescription       : OK
ProtocolVersion         : 1.1
ResponseUri             : http://www.google.com.au/?gfe_rd=cr&ei=I7M0U5P_BenC8gfRvIHADg
Method                  : HEAD
IsFromCache             : False

Based on this, you could check the statuscode or statusdescription properties of $res to make sure the value matches "OK".

Alternatively, if you enter an invalid URL for a website that doesn't exist, you will get an error, and the value of $res will be $null. The error you get will be something along the lines of;

Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: (502) Bad Gateway."
At line:4 char:46
+ [net.httpWebResponse] $res = $req.getresponse <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

Wednesday, 26 March 2014

Get Folder Size (including subfolders) with Powershell

The method for obtaining the size of all items within a folder using Windows Powershell is unfortunately not as straight forward as it probably should be. The method outlined below is very useful for querying multiple folders to determine the size of all items inside, including all subfolders and files.

$dir = "C:\temp"
$totaldirsize = (get-childitem $dir -recurse -force | measure-object -property length -sum)

The first variable sets the directory that we wish to query - in this example it is C:\temp.

Next, we use a get-childitem to query the directory. The -recurse and -force switches mean that all sub directories and files are also included. We then pipe the results to measure-object and calculate the length of each child item (which is actually the size in bytes) and use the -sum switch to add them all up.

If you run the above command, and then look at the $totaldirsize variable, you will see something like below;

PS C:\> $totaldirsize

Count    : 38
Average  : 
Sum      : 51652089
Maximum  : 
Minimum  : 

Property : length

So from this we can see there are 38 items in total in the C:\temp directory, and the sum of all files is 51652089 bytes. To make this more useful, we can easily convert this value to KB, MB or GB

$mbsize = $totaldirsize.sum / 1MB

If we now look at $mbsize, we'll usually have an integer with a large number of decimal places. In this example, the result I got was 49.2592706680298. So as a final step, I'd like to round this number to 2 decimal places

$mbsize2 = "{0:N2}" -f $mbsize

Now if we look at the value of $mbsize2, the result is 49.26.

You can change the 2 in {0:N2} to any other digit to round the number to that many places after the decimal point.

Friday, 8 February 2013

Querying Exchange Mailboxes with Powershell Pt 2

In my previous blog post, I outlined some methods to query Exchange mailboxes using the get-mailbox cmdlet. Whilst the information obtained using this cmdlet is very useful, it does not contain all the information that is available for an Exchange mailbox.

There is another cmdlet available called Get-MailboxStatistics. It is used/applied in the same way as the Get-Mailbox cmdlet, but contains different fields or properties, and therefore, different information relating to the mailbox.

If you run the command Get-MailboxStatistics -identity "MailboxName" | fl it will display the mailbox statistics for that particular mailbox.

This information includes;

  • Associated item count (ie. number of items within the mailbox)
  • Deleted item count
  • Last logon/logoff time
  • Total size of items
  • Total size of deleted items
So, for a practical example that you could potentially use to query this information. Let's say you want to query all your mailboxes to identify those that have more than 20,000 items within them. You could run the following command;

Get-Mailboxstatistics | Where {$_.ItemCount -gt "20000"} | Select DisplayName

You could replace $_.ItemCount with any of the other properties that are contained within the Get-MailboxStatistics cmdlet.

If you want the query to return more than just the DisplayName field for objects that match your query, you can add them after DisplayName and separate them with a comma (,), or if you want to return all properties then remove | Select DisplayName altogether.

You can also add | Export-CSV-path "C:\Export.csv" -notype to the end to export your query results to a .csv file.

Tuesday, 5 February 2013

Querying Exchange Mailboxes with Powershell

Exchange and Powershell go hand in hand - as it is essentially what Exchange is built on top of, and is what the Exchange Management Console (EMC) uses to execute commands you choose through the GUI. (Ever noticed you get the Powershell command line equivalent for commands you execute in EMC?)

One of the most common things an administrator will need to do is query all the mailboxes within the system for certain criteria, which I will explain and breakdown in this blog entry.

The command Get-Mailbox is one of the most useful and powerful commands you can use (for information gethering). It can be used to retrieve all the properties for all the mailboxes in your system, or can be tweaked to only return some of the properties for some of the mailboxes within your system.

If you execute the command Get-Mailbox on its own, you will probably be flooded with 1000 responses, followed by the following warning message;


WARNING: By default only the first 1000 items are returned. To change the number of items returned, specify the parameter "-ResultSize". To return all items specify "-ResultSize Unlimited" (Note: Returning all items may take a 
very long time and consume a large amount of memory depending on the actual number of items). It is not recommended to store the results in a variable; instead pipe the results to another task or script to perform batch changes

As per the message, the command on its own will only return the first 1000 results. You can change this by adding -ResultSize Unlimited to it, so it would look like this;

Get-Mailbox -ResultSize Unlimited

If you run this command it will run through and display the first few properties for every mailbox within your system. While this can be useful, the command can be further tweaked to run faster and provide more accurate/informative results.

To get all the properties for a single users mailbox, you can use the following command

Get-Mailbox -Identity "Morrissey, Peter"

You can replace what is between the " " with any identifier for the mailbox - such as Primary SMTP Address, Display Name or Alias.

When you run this command it will only display the first few properties as it is presenting the information in a table format. If you change the command to display in list format (by adding | fl), you get MUCH more information:

Get-Mailbox -Identity "Morrissey, Peter" | fl

Now you can view ALL the properties for an individual users mailbox. These properties apply to every mailbox within the system, so you can once again, modify the Get-Mailbox command to search on any of the properties you see in this list.

For example, if I wanted to query all the mailboxes within my system, and only return those whose 'Name' property contain the text "Peter", I would run the following command

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"}

You still need to include -Resultsize Unlimited because although you aren't expecting more than 1000 results to be returned, you do want the Get-Mailbox command to query more than the first 1000 mailboxes, which it will not do if this omitted.

You can replace the $_.Name with any of the other properties for a mailbox - it just needs to have the $_. before it.

The -like operator can also be changed to use -eq (equal to) -ne (not equal to) -gt (greater than) -lt (less than) -le (less than or equal to) -ge (greater than or equal to)

Next you can fine tune the properties that you wish to display for each object whos name contains "Peter". Say you want to only display the DisplayName, Alias, Database and PrimarySMTPAddress properties for each of the results. You could use the following line

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"} | Select DisplayName, Alias, Database, PrimarySMTPAddress

The benefit of doing this is that by retrieving fewer properties for each object, it speeds up the time it takes for the query to run. It also makes looking through the results much faster as you aren't reading over information you don't need. Once again, you can replace the properties I used with any of the properties available for each mailbox, as we discovered earlier.

Finally, you  can export the results of your query to a CSV file

Get-Mailbox -ResultSize Unlimited | Where {$_.Name -like "*Peter*"} | Select DisplayName, Alias, Database, PrimarySMTPAddress | Export-CSV -path "C:\Export.csv" -notype

Once you have the information in a CSV file you can attach it to an email and send it to yourself (or someone else) as per my previous blog post

Thursday, 24 January 2013

Exporting Exchange Distribution Group Members with Powershell

Before making any major changes to distribution groups, I like to take a backup of the current membership lists prior to making any changes. Particularly in cases where membership lists are quite large, it's always better to be safe than sorry for when a user or distribution group owner wants to know who was a member prior to making the change.

Getting the list of members and exporting it to a simple .csv file can be achieved using the Powershell script below.

Note that you should change the first two (2) variables ($DLName and $ExportFilePath) accordingly.

#Script to get/export list of all distribution group members
#Date Created: 24th January, 2013
#Author: Peter Morrissey


#Enable Exchange cmdlets
add-pssnapin *exchange* -erroraction SilentlyContinue

$DLName = "DL_Example_List"
$ExportFilePath = "C:\Export\Export.csv"


$MemberList = get-distributiongroupmember -identity $DLName

ForEach ($Member in $MemberList){write-output "$($member.name)" | out-file -filepath "$exportfilepath" -append -noClobber}