Subscribe
Search

Entries in powershell (60)

Sunday
Oct022011

PowerShell DNS Week

The next few days worth of scripts will be focusing on PowerShell scripts which modify DNS.

Thursday
Sep292011

Quest Active Directory CmdLets and Distribution Groups

All sysadmins will at soem point be required to clean up/report on Microsoft Exchange distribution groups within their organisation. Below are some notes I made as I was working on them recently.

Note: All of these use the Quest AD Cmdlets

I had a array of groups that had been passed to me ($groups), I wanted to add to that array the name of the user who manages that group, before passing the variable on to other things:

Function Get-ManagedbyName {
[cmdletbinding()]           

Param (
     [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True, `
            HelpMessage="You must specify a QAD group object")]
     [Quest.ActiveRoles.ArsPowerShellSnapIn.Data.ArsGroupObject]$group
    )           

Begin {
    Write-Verbose "Starting function"
}           

Process {
    $managedby = $group.managedby
    $managedname = ""
    if (($managedby -eq "") -or ($managedby -eq $null)) {
        $managedname =  ""
    } else {
        $managedname = (get-qaduser $managedby).name
    }
    $group | Add-Member -MemberType NoteProperty -Name "ManagedbyName" `
          -Value $managedname -passthru
}           

End {
    Write-Verbose "Ending function"
}           

An example of using this would be

$groups= <get your group>

$groups| Get-ManagedbyName

A cmdlet to hide groups from the global address list:

Function hide-distributionlist {
[cmdletbinding()]           

Param (
     [Parameter(Position=0, Mandatory=$True, ValueFromPipeline=$True,
     HelpMessage="You must specify a list of groups")]
     [System.string[]]$groups
    )

Begin {
    Write-Verbose "Starting hide-distributionlists"
}           

Process {
    foreach ($group in $groups)
    {
       #move the group to:
       Move-QADObject $group -newparentcontainer "OU=disabled mailing groups, `
            OU=disabled users,OU=CSAU,DC=sunqld,DC=com,DC=au"
       #hide from addresslist
       set-qadgroup $group -objectattributes @{MSExchHideFromAddressLists=$true}
   }
}           
End {
    Write-Verbose "Ending hide-distributionlists"
}           

}

Tuesday
Aug232011

Automating Nmap analysis with PowerShell

Nmap is one of the best tools in a sysadmin's toolkit; this powerful tool allows us to quickly determine what computers and devices are on our network, what software and operating systems are running.

In most environments, esp. when there are a large number of servers and workstations in quite a number of subnets, its handy for system administrators to be able to easily find a free IP address.

There have been several times when various security managers have requested to know the following items:

  • All servers/workstations that are up
  • Are the following services running: SSH, Telnet, FTP, HTTP, HTTPS, RDP, SMTP
  • Is there anonymous FTP?
  • Is there anonymous FTP uploads?

Nmap is obviously the tool to complete the task to find out this information. If we could automate this, then we could easily generate reports for upper management!

Thankfully, the guys over at SANS have already completed most of the work for us. In the post: PowerShell Script To Parse nmap XML Output, the provide a script which gets Nmap XML output and makes it into a format that allows any powershell user to manipulate the results using all the usual commands (format-table, format-list, where-object, select-object).

I developed a simple script to find IP addresses that were in use and provide a simple output that any system administrator or service desk operator could read. The script is simple, and does the following tasks for each subject listed in an array:

  1. Make a user friendly filename
  2. Run nmap to perform a number of ICMP and TCP scans to find servers that are up (I recommend TCP SYN scanning on top of ICMP Ping to ensure you find firewall protected servers and workstations)
  3. Parse the results of nmap and put them into a file in a more friendly format

 

The script looks like this:

 

nmap Command breakdown:

-PS20,21,22,23,25,3389,80,443,8080 is a TCP SYN Ping sweep of the subnet of ports 20, 21, 22 etc

-PE is ICMP ping (usual ping command)

-R is perform a reverse DNS look up

--dns-servers is specifying all of our DNS servers (incase you have reverse lookup zones across differing DNS servers)

-p 20,21,22,23,25,3389,80,443,8080 we want to scan these ports for possible reports later on

-oX $nmapfile --no-stylesheet outout the results to the filename and don't use a XML sylesheet

-A enable all advanced options

-v we want verbose output for reporting.

We end with the subnet we want to scan.

Sunday
Aug212011

PowerShell RoboCopy Wrapper

So I find myself copying files from point A to point B on a regular basis, so much so, that I find myself using robocopy in a Windows scheduled task. The problem with this approach, is that there isn't many easy ways of working out if it worked, or worse, if something bad has happened!

I bashed out a script several years ago, and finally updated it to make use of the template that I posted up previous.

There are a few things to note with the script:

  • I always check if the source and destination exist, and report an error if they don't
  • My scripts always use the /MIR command, and limit retries to 3
  • Robocopy return codes:
    0: Completed sucessfully, but didn't copy any files
    1: Completed sucessfully and copied files
    rest: some error has occured

The bulk of the code is:

#robocopy task
$result = robocopy $source $destination /MIR /R:3

#robocopy sucess is:     0: no errors, but no copying done
#                        1: one or more files were copied sucessfully

#check there were no errors in the robo copy
if ($lastexitcode -gt 1)
{
    if ($lastexitcode -eq 0)
    {
        $messagebody = "Robocopy completed but no files copied! `n"
        foreach ($x in $result) {$messagebody = $messagebody + $x + "`n"}
        send-email $messagebody $false
    } elseif ($lastexitcode -eq 1)
    {
        #do nothing, it worked
    } else {
        $messagebody = "Robocopy returned an unknown error! `n"
        foreach ($x in $result) {$messagebody = $messagebody + $x + "`n"}
        send-email $messagebody $false
        exit 3
    }
}

The entire script is in the samples section, here.

Saturday
Jun112011

Powershell Script Template

Just a quick post to cover layout/format of all PowerShell scripts I write.

This default template ensures that a sufficient amount level of of quality is ensured in all scripts. There are several things you will notice:

  • All scripts start with param definitions, which include items for the functionality for that script (both mandatory and option) as well as variables used to support features other basic functions
  • Email alerting on success of failure with option to turn off or on both, either, or no email alerts
  • I use exit calls, I know this is probably considered bad, but as you can see, it makes it easier to troubleshoot

 

And here it is (you can download it here):

 

# ==============================================================================================
#
# Microsoft PowerShell Source File -- Created with SAPIEN Technologies PrimalScript 2009
#
# NAME: <name of script which will be helpful>
#
# AUTHOR: <author>
# DATE  : <date>
#
# COMMENT: <Step through what this script does
#
# ==============================================================================================

#<place comments used to assist in the calling of the script

param(
    #<application specific params>
    
    #<email and alerting params>
    [Parameter(Position=3, Mandatory=$false, HelpMessage="Specify email alert recipient address")]$recipient="user@user.com",
    [Parameter(Position=4, Mandatory=$false, HelpMessage="Specify email alert from address")]$from="user@user.com",
    [Parameter(Position=5, Mandatory=$false, HelpMessage="Specify smtp server name/ip")]$smtpserver="smtp.server.com",
    [Parameter(Position=6, Mandatory=$false, HelpMessage="Alert on sucessfuly copy")]$emailonsuccess=$true,
    [Parameter(Position=7, Mandatory=$false, HelpMessage="alert on failure of copy")]$emailonfailure=$true,
    [Parameter(Position=8, Mandatory=$false, HelpMessage="alert email subject")]$emailsubject="<change to be helpful subject>"
)

#
#variable declarations
        

function send-email ($body, $success)
{
    #incase we are troublshooting, output the body here
    $body
    
    $error.clear()
    #if it is sucessful
    if ($success)
    {
        #if we want a successful emails
        if ($emailonsuccess)
        {
            $subject = $emailsubject + "- Success"
            Send-MailMessage -To $recipient -From $from -SmtpServer $smtpserver -Subject $subject -Body $body -bodyashtml
        }                 
    }
    else #if unsuccessful
    {
        #if we want emails on failure
        if ($emailonfailure)
        {       
            $subject = $emailsubject + "- Failure"
            Send-MailMessage -To $recipient -From $from -SmtpServer $smtpserver -Subject $subject -Body $body -bodyashtml
        }                    
    }
    
    if ($error)
    {
        "Unable to send an email"
        exit 666
    }                                                                                                                  
}                                                                                                                           

#
# If we expect a crash/error here is an example (this is using $error but it could be try catch or based on $lastexitcode for external calls
#
$error.clear()
#do something bad
somethingbad()
if ($error)
{
    send-email "<sad>" $false
    exit 7
}


#email that we got here successfully
send-email "<HAPPY>" $true

Page 1 ... 8 9 10 11 12