Archive

Archive for the ‘Guides’ Category

Scheduling Powershell scripts in Windows Task Scheduler

May 29th, 2011 No comments

In order to schedule a PowerShell script to run as a scheduled task in Windows Server 2003 you will need to use the following command syntax. I also set the “Start In” directive to the directory that contains the .ps1 file. The command below will cause the script to run in the background and not generate a window while it is running.

C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -nologo -command "& {path\to\script.ps1}"
Categories: Windows Tags:

Creating a Junos Olive in VMware

May 29th, 2011 5 comments

The termĀ  “Olive” is given to any virtual machine or PC based hardware platform that is running the Junos operating system on it. Juniper does not support these types of installations. Below is the walk through of how I got the Junos Olive created for my lab environment. You will need a copy of the FreeBSD 4.11 Mini Installation ISO image (available here)and a Junos software package. I’m using Junos 10.4R3.4 for the M/MX/T series routers. I will not provide the Junos image for download, you will need a valid J-Care contract to download the software from Juniper.

Create a virtual machine with the following settings (I’m using VMware Workstation).

  • 1 Processor
  • 512 MB Memory
  • CD-ROM Drive (for FreeBSD install)
  • Remove the USB Adapter & Sound Card
  • 8 GB Hard Drive (I used the default drive size)
  • Add as many network adapters as necessary (you can always add or remove network interfaces later)

Once you have created the virtual machine, edit the virtual machine configuration file (.vmx) file and make the following changes.

Change the below entry to FALSE

scsi0.present = "FALSE"

Make sure the network adapters are set to “e1000″

ethernet0.virtualDev = "e1000"

Next install FreeBSD 4.11 with the following settings:

  • Standard installation
  • FDisk – Use entire disk
  • BootMgr – default FreeBSD Boot Manager
  • Create the following partition structure:
    Part        Mount           Size
    -----     ---------        ------
    ad0s1a     /                512M
    ad0s1b     swap            1024M
    ad0s1e     /config           24M
    ad0s1f     /var          use rest of space
  • Average User install
  • Do not install the ports collection
  • Installation Media – CD/DVD
  • Choose Yes on the final warning message
  • Would you like to configure any Ethernet or SLIP/PPP network devices? Yes
  • Configure em0 with no IPv6 support and enable DHCP
  • Do you want this machine to function as a network gateway? No
  • Do you want to configure inetd and the network services that it provides? No
  • Do you want to have anonymous FTP access to this machine? No
  • Do you want to configure this machine as an NFS server? No
  • Do you want to select a default security profile for this host? No
  • Would you like to customize your system console settings? No
  • Would you like to set this machine’s time zone now? No
  • Would you like to enable Linux binary compatibility? No
  • Does this system have a non-USB mouse attached to it? No
  • Package collection – Would you like to browse the collection now? No
  • Any additional user accounts? No
  • Set the root password
  • Visit the general configuration menu for a chance to set any last options? No
  • Exit the installation and let the system reboot

Log into the virtual machine as root and place the jinstall-*-domestic-signed.tgz file in /var/tmp. Since this is not a Juniper device you will need to modify the contents of the package to get it to install on FreeBSD. Replace the asterisk’s in the jinstall file names with the version you downloaded.

  1. Create a jinstall directory and extract the contents of jinstall-*-domestic-signed.tgz into it.
    cd /var/tmp
    mkdir jinstall && tar -C jinstall -zxf jinstall-*-domestic-signed.tgz
  2. Edit the +INSTALL file in the jinstall directory and change the check_arch function to match below.
    vi -- +INSTALL
     
    check_arch_compatibility()
      {
        # re_name=`/sbin/sysctl -n hw.re.name 2>/dev/null`
        re_name="olive"
        if [ -z "$re_name" ]; then
            Error "hw.re.name sysctl not supported."
        fi
  3. Extract the contents of jinstall-*-domestic.tgz to /var/tmp/jinst-dom
    mkdir /var/tmp/jinst-dom && tar -C /var/tmp/jinst-dom -zxf jinstall-*-domestic.tgz
  4. Change directories to /var/tmp/jinst-dom and make the same change to both the +INSTALL and +REQUIRE files in this directory.
  5. Extract the contents of /var/tmp/jinst-dom/pkgtools.tgz and replace the program checkpic with /usr/bin/true.
    mkdir /var/tmp/pkgtools && tar -C /var/tmp/pkgtools -zxf pkgtools.tgz
    cp /usr/bin/true /var/tmp/pkgtools/bin/checkpic
  6. Change directory to the pkgtools directory and create a gzipped tar file of the contents. Then move the pkgtools.tgz file to /var/tmp/jinst-dom.
    tar czf pkgtools.tgz *
    mv pkgtools.tgz /var/tmp/jinst-dom/
  7. Change directory to the jinst-dom directory and create a gzipped tar file of the contents. Then move the jinstall-*-domestic.tgz to /var/tmp/jinstall.
    tar czf jinstall-*-domestic.tgz *
    mv jinstall-*-domestic.tgz /var/tmp/jinstall/
  8. Change directory to /var/tmp/jinstall. Before creating the tar file you will need to delete the signature files as the check-sums will no longer match.
    rm -f *.md5 *.sha1 *.sig
    tar czf /var/tmp/jinstall-*-olive.tgz *
  9. Install the package we just created with pkg_add. You will receive some warning messages which are to be expected.
    pkg_add jinstall-*-olive.tgz

Once the install is completed reboot the virtual machine, after a few minutes you should be presented a login prompt. The default username is root and there is no password. At this time you are now able to type ‘cli’ and enter the Junos command line. Now you can copy this virtual machine to create the number of Olive’s you need for your lab.

Categories: Networking Tags: ,

Powershell – Downloading and extracting Zip files from FTP

December 5th, 2010 2 comments

Recently I had the need to routinely check for zip files on a remote FTP server, if there were new files download them and extract them into a particular directory. Dreading the addition of yet another manual process I set out to build a Powershell script to accomplish this task for me. I had become quickly frustrated with the lack of native FTP support in the .Net framework, I know you could pass the ftp credentials as a parametrized URL and download single files. However, I needed to perform a directory listing to see which files existed and had not been downloaded previously. In my search I came across the Indy Project an Open Source group that wrote and maintains the Indy Sockets library which includes and FTP client socket among other things. I will also distribute the Indy.Sockets library with my script.

In this script the $workingPath refers to the location that you want to store the files after downloading and extracting them. This script provides some basic logging functionality, the log file will be written to C:\FTPUtil\FTPUtil.log.

# Downloads files from an FTP server and unzips them.
# The script will only download new files that have not
# been previously downloaded and extracted into the
# working directory. This can be setup as a scheduled
# task to automate script run-time. Basic logging is
# is written into the FTPUtil.log text file in the 
# application directory.
#
# Created by Dustin Berube on 11/16/2010.
# Requires Indy.Sockets.dll and Mono.Security.dll version=1.0.5000.0
 
# Base Location of Files to work with
$workingPath = 'x:\path\to\your\file\location'
 
# File Extension
$fileExt = '.ZIP' # File extension of file you are downloading.
 
# FTP Information
$ftpDir 	= "/directory"  			# Directory path to folder on ftp server
$ftpServer 	= "ftp.yourserver.com"		# FTP Server address
$ftpUser 	= "username" 				# FTP Username
$ftpPass 	= "password" 				# FTP Password
 
# Application Directory - Usually C:\FTPUtil unless installed to different directory
$appDir = 'C:\FTPUtil'
 
#
# DO NOT CHANGE ANYTHING BELOW THIS LINE
#
 
set-location $workingPath
$shell = new-object -com shell.application
 
function unzip-Files {
	$location = $shell.namespace($workingPath)
	$zipFiles = get-childitem *.zip
 
	if (Test-Path ($workingPath + "\*$fileExt")) {
	foreach ($zipFile in $ZipFiles) {
		$destDirectory = ($workingPath + "\" + $zipFile.name.Trim($fileExt))
		if (!(Test-Path -path $destDirectory)) {
			[IO.Directory]::CreateDirectory($destDirectory) | out-null
			$location = $shell.namespace($destDirectory)
			$zipFolder = $shell.namespace($zipFile.fullname)
 
			$location.copyhere($zipFolder.items())
			((get-date).ToString() + " --- " + $zipFile.name + " extracted to $destDirectory") | out-file "$appDir\FTPUtil.log" -append
		}
	}
	Remove-ZipFiles
	}
	else {
		((get-date).ToString() + " --- NO FILES DOWNLOADED AND UNZIPPED") | out-file "$appDir\FTPUtil.log" -append
	}
}	
 
function Remove-ZipFiles {
	set-location $workingPath
	$location = $shell.namespace($workingPath)
	remove-item "*$fileExt"
}
 
function Open-FTPConnection {
	# Load Indy Sockets Library
	[Reflection.Assembly]::LoadFrom("C:\ftputil\Indy.Sockets.dll") | Out-Null
 
	$ftp = new-object Indy.Sockets.FTP
	$ftp.Disconnect()
 
	# Connect to FTP Server
	$ftp.Host = $ftpServer
	$ftp.Username = $ftpUser
	$ftp.Password = $ftpPass
	$ftp.Connect()
 
	# Set PASV mode
	$ftp.Passive = $true
 
	return $ftp
}
 
function Close-FTPConnection($ftp) {
	$ftp.Disconnect()
}
 
function Download-FTPFile($ftp) {
	$ls = new-object System.Collections.Specialized.StringCollection
	$ftp.List($ls, $ftpDir, $false)
	foreach($file in $ls) {
		$fileName = $file.Trim("$ftpDir/")
		if (!(Test-Path -path ($workingPath + "\" + $fileName.Trim($fileExt)))) {
			 $ftp.Get($file, ($workingPath + "\$fileName"), $true, $false)
			 ((get-date).ToString() + " --- $fileName Downloaded and saved to $workingPath") | out-file "$appDir\FTPUtil.log" -append
		}
	}
}
 
$f = Open-FTPConnection
Download-FTPFile $f 
Close-FTPConnection $f
unzip-Files

After downloading this script, extract the contents to C:\FTPUtil. You can download the FTPUtil script from here http://www.dustinberube.com/files/FTPUtil.zip. As always I take no responsibility for any problems that arise from the use of this script, it has been tested and used in my development and production environments without issue.

Using Procmail to route messages to Request Tracker (RT) queue’s

November 14th, 2010 2 comments

At work we use Request Tracker (RT) by Best Practical to handle our help desk e-mail and public correspondence e-mail queue’s. When setting up RT you would typically provide different e-mail addresses for each queue and have people e-mail the appropriate address to submit a question or trouble ticket. In some organizations such as ours your support base is already use to a mechanism that was put in place of everyone emailing a single address such as support@yourcompany.com. In my situation it would have been very difficult to change this because of all the outside agencies that also use this support address. Good news is there is an answer to this problem called Procmail.

This guide is based off of CentOS 5.5 with Postfix as the MTA and the latest Procmail available via ‘yum’. The location of the configuration files may be different in your Linux distribution of choice.

First we need to tell Postfix to pass the mail to an external command for further processing Add this command to your /etc/postfix/main.cf configuration file.

[dberube@itsupport ~]$ sudo vi /etc/postfix/main.cf
 
# The mailbox_command parameter specifies the optional external
# command to use instead of mailbox delivery. The command is run as
# the recipient with proper HOME, SHELL and LOGNAME environment settings.
# Exception:  delivery for root is done as $default_user.
#
# Other environment variables of interest: USER (recipient username),
# EXTENSION (address extension), DOMAIN (domain part of address),
# and LOCAL (the address localpart).
#
# Unlike other Postfix configuration parameters, the mailbox_command
# parameter is not subjected to $parameter substitutions. This is to
# make it easier to specify shell syntax (see example below).
#
# Avoid shell meta characters because they will force Postfix to run
# an expensive shell process. Procmail alone is expensive enough.
#
# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
#
mailbox_command = /usr/bin/procmail

After modifying the Postfix main.cf file we need to create our Procmail ruleset which will be saved in this file /etc/procmailrc.

[dberube@itsupport ~]$ sudo vi /etc/procmailrc
 
# Set Variables
SHELL=/bin/sh
LOGFILE=/var/log/procmail_log
LOG="--- Logging ${LOGFILE} for ${LOGNAME} ---\\n"
VERBOSE=yes
RT_MAILGATE="/opt/rt3/bin/rt-mailgate"
RT_URI="http://itsupport.domain1.local/ticket"
 
LOGABSTRACT=no
 
# Accounts Payable
:0
* ^TO_.*rt-ap@
|/usr/bin/perl $RT_MAILGATE -queue "Accounts Payable" --action correspond --url $RT_URI
 
# Value Adjustment Board
:0
* ^TO_.*rt-vab@
* ^TO_.*vab@
|/usr/bin/perl $RT_MAILGATE -queue "Value Adjustment Board" --action correspond --url $RT_URI
 
# Domain 1
:0
* ^From: .*@domain1.com
 {
        :0
        * ^Subject:.*benchmark
        |/usr/bin/perl $RT_MAILGATE -queue "Benchmark" --action correspond --url $RT_URI
 
        :0
        |/usr/bin/perl $RT_MAILGATE -queue "Office Queue" --action correspond --url $RT_URI
}
 
# Domain 2
:0
* ^From: .*@domain2.com
|/usr/bin/perl $RT_MAILGATE --queue "Domain 2" --action correspond --url $RT_URI
 
# Domain 3
:0
* ^From: .*@domain3.com
|/usr/bin/perl $RT_MAILGATE --queue "Domain 3" --action correspond --url $RT_URI
 
# All Others
:0
* !^From: .*@domain1.com|.*@domain2.com|.*@domain3.com
|usr/bin/perl $RT_MAILGATE --queue "External Users" --action correspond --url $RT_URI

You will notice that the rule set for Domain 1 looks a little different than the other rules. For messages that are arriving to my RT server from @domain1.com I am checking for the subject line as well. If any message arrives from domain1.com that has the word “benchmark” in the subject line send it to the “Benchmark” queue. If that check does not match the email will be placed in the “Office Queue”. Most of these rules are self-explanatory so I won’t go into the details of every rule, the one other rule that I believe is worth talking about is the last one in the rule set. My “All Others” rule says that is an incoming email message to my support email address does not match domain1, domain2 or domain3 place it in the “External Users” queue.

I hope this helps you find alternative ways to handle e-mail processing with RT. In the future I will be posting more guides on how to configure RT in an Microsoft Active Directory and Exchange Server environment.

Categories: Linux Tags: , , ,

Reset Home Folder Permissions

September 28th, 2010 No comments

This week we had an incident occur at work that required all the home directory permissions reset for all users in Active Directory. You basically have two options to reset the permissions do it manually or write a script. Have you thought about which option you would take? Of course you have, a good Systems Administrator would rather write a script to conduct this mundane task. Below is my PowerShell script to add the user back with rights to their directory. It will not overwrite permissions as it uses the default behavior of Windows Server 2003 and Active Directory, which is to have home directories inherit the parent folders NTFS rights.

This script also requires the Active Directory Management pack from Quest Software (free download).

# Load Quest Active Directory Snap-in
add-pssnapin quest.activeroles.admanagement
 
# Get list of users that have home folders on the SAN. Creates an array of objects
$users = get-qaduser -size 1000 | select logonName,homeDirectory | where {$_.homeDirectory -like '\\path\to\users\*'}
 
# Loop through $users array
foreach ($x in $users) {
 
    # Check to see if directory exists. If not write error message to console.
    if (test-path $x.homeDirectory) {
 
        # Build ACL and grant user modify rights to their respective folder. Also propagates the access rule to subfolder and files.
        $acl = get-acl $x.homeDirectory
        $inherit = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit","ObjectInherit"
        $prop = [system.security.accesscontrol.PropagationFlags]"InheritOnly"
        $ar = new-object system.security.accesscontrol.filesystemaccessrule($x.LogonName,"Modify", $inherit, $prop, "Allow")
 
        $acl.SetAccessRule($ar)
 
        # Set ACL on directory
        set-acl $x.homeDirectory $acl
    }
    else {
        write-host $x.homeDirectory "does not exist."
    }    
}
 
write-host "All folder permissions have been changed. Any errors have been listed above."

I hope this script will help someone else accomplish this task.