“Free Ice Cream” – Harmless Office Email Prank Utilizing PowerShell

Unfortunately, I was caught when trying to manually send an email today when someone left their computer unlocked.

So, next time around, I’m prepared..

$OUTLOOK = "C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE"

function generateParticipants {
    $PARTICIPANT_LIST = $args[0]

    $PARTICIPANT_STRING_TO_RETURN = ""

    foreach ($PARTICIPANT in $PARTICIPANT_LIST) {
        $PARTICIPANT_STRING_TO_RETURN = $PARTICIPANT_STRING_TO_RETURN + ";" +  $PARTICIPANT
    }

    $PARTICIPANT_STRING_TO_RETURN = $PARTICIPANT_STRING_TO_RETURN + ";" + $PERSON_EMAIL

    return $PARTICIPANT_STRING_TO_RETURN
}

function createEmail {
    $SUBJECT = $args[0]
    
    $BODY = $args[1]
    
    $TO_ARRAY = $args[2]

    $TO = generateParticipants $TO_ARRAY

    $MEETING_CONTENTS = "$TO&subject=$SUBJECT&body=$BODY"

    Start-Process -WindowStyle Maximized -FilePath "$OUTLOOK" -ArgumentList "/c  ipm.note /m `"$MEETING_CONTENTS`""
}

$EMAIL_SUBJECT = "Free Ice Cream!"
$EMAIL_BODY = "I'm Buying."

$PARTICIPANT_LIST = New-Object Collections.Generic.List[String]

$PARTICIPANT_LIST.Add("person1@company.com")
$PARTICIPANT_LIST.Add("person2@company.com")
$PARTICIPANT_LIST.Add("person3@company.com")

createEmail $EMAIL_SUBJECT $EMAIL_BODY $PARTICIPANT_LIST

Automatic/Simple WebLogic Application Manipulation and Deployment Script Utilizing Bash

Today I come to you with a fun script I wrote to manipulate applications in WebLogic.

Using the weblogic.Deployer class in the WebLogic JAR we are able to Automate and Simplify some of the more mundane tasks that we all have to do in WebLogic sometimes.

For the savvy, please refer to the “prerequisites()” function and uncomment/comment whatever things you want the user to enter for proper security and portability.

Gotta love that dumb generic 1/2/3/4/5 menu interface I keep using.

Below is the code:

#!/bin/bash

#These Variables are here purely for initialization 
#and are overwritten when the prerequisites()
#function is called down at bottom of script

USERNAME=""
PASSWORD=""

ADMIN_URL="" #the url for deployment
JAVA_PATH="/usr/java/latest/bin/java" #path to java

WEBLOGIC_JAR="" #my weblogic server path
TARGET="" #values can be seperated
APPLICATION_NAME="" #the deployment name 
APPLICATION_PATH="" #the path to the ear file

WEBLOGIC_DEPLOYER_CMD="$JAVA_PATH -cp $WEBLOGIC_JAR weblogic.Deployer -verbose -debug -adminurl "$ADMIN_URL" -username $USERNAME -password $PASSWORD "

prerequisites()
{
    #In this command you can uncomment/comment variable declarations you want the user to enter every time

    echo "Type The Application Name: "
    read APPLICATION_NAME

    #echo "Type The Target JVM Servers (Space Between Each JVM Name): "
    #read TARGETS
    TARGETS="AdminServer"

    #echo "Type WebLogic Admin Username: "
    #read USERNAME
    USERNAME="weblogic"

    #echo "Type WebLogic Admin Password: "
    #read PASSWORD
    PASSWORD="password1"

    #echo "Type AdminServer Protocol (t3 - not secure) or (t3s - secure): "
    #read ADMIN_PROTOCOL
    ADMIN_PROTOCOL="t3"

    #echo "Type AdminServer Hostname: "
    #read ADMIN_HOSTNAME
    ADMIN_HOSTNAME="localhost"

    #echo "Type AdminServer Port: "
    #read ADMIN_PORT
    ADMIN_PORT="8080"

    #This Sets the ADMIN_URL for WebLogic Connection
    ADMIN_URL="$ADMIN_PROTOCOL://$ADMIN_HOSTNAME:$ADMIN_PORT"

    #echo "Type the path to the Java Binary: "
    #read JAVA_PATH
    JAVA_PATH="/usr/java/latest/bin/java"

    #echo "Type the path to the WebLogic JAR: "
    #read WEBLOGIC_JAR
    WEBLOGIC_JAR="/home/oracle/Oracle/Middleware/Oracle_Home/wlserver/server/lib/weblogic.jar"

    #This Sets the Command for Application Manipulation Later On
    WEBLOGIC_DEPLOYER_CMD="$JAVA_PATH -cp $WEBLOGIC_JAR weblogic.Deployer -verbose -debug -adminurl "$ADMIN_URL" -username $USERNAME -password $PASSWORD "
    
    choiceFunction
}

baseCommand()
{
    CHOSEN_OPTION="$1"
    EXTRA_ARGS="$2"

    $WEBLOGIC_DEPLOYER_CMD $CHOSEN_OPTION -name "$APPLICATION_NAME" -targets "$TARGETS" $CHOSEN_OPTION $EXTRA_ARGS
    
    echo "FINISHED EXECUTION - PRESS ENTER TO CONTINUE..."
    read NOTHING

    choiceFunction
}

application_start()
{
    PARAMETER_CHOSEN_OPTION="-start"
    PARAMETER_EXTRA_ARGS=""
    baseCommand "$PARAMETER_CHOSEN_OPTION" "$PARAMETER_EXTRA_ARGS"
}

application_stop()
{
    PARAMETER_CHOSEN_OPTION="-stop"
    PARAMETER_EXTRA_ARGS=""
    baseCommand "$PARAMETER_CHOSEN_OPTION" "$PARAMETER_EXTRA_ARGS"
}

application_undeploy()
{
    PARAMETER_CHOSEN_OPTION="-undeploy"
    PARAMETER_EXTRA_ARGS=""
    baseCommand "$PARAMETER_CHOSEN_OPTION" "$PARAMETER_EXTRA_ARGS"
}

application_deploy()
{
    PARAMETER_CHOSEN_OPTION="-deploy"

    echo "Type Full Java WAR/EAR Path: "
    read APPLICATION_PATH

    PARAMETER_EXTRA_ARGS="-upload $APPLICATION_PATH"

    baseCommand "$PARAMETER_CHOSEN_OPTION" "$PARAMETER_EXTRA_ARGS"
}

# Bash Menu Script Example
choiceFunction() {
    SUCCESS="false"
 
    while [ $SUCCESS == "false" ]
    do
        clear
        echo "Please enter your choice: "
        echo "1 - Start WebLogic Application"
        echo "2 - Stop WebLogic Application"
        echo "3 - Undeploy WebLogic Application (Stop Application First Please)"
        echo "4 - Deploy WebLogic Application"
        echo "5 - Quit"
        read CHOICE
 
        case $CHOICE in
           "1") SUCCESS="true";echo "Executing Application Start ..."; application_start;;
           "2") SUCCESS="true";echo "Executing Application Stop ..."; application_stop;;
           "3") SUCCESS="true";echo "Executing Application Un-Deployment (Removal) ..."; application_undeploy;;
           "4") SUCCESS="true";echo "Executing Application Deployment ..."; application_deploy;;
           "5") SUCCESS="true";echo "Exiting ..."; exit;;
           *) read -p "Invalid choice, Press any key to continue..." fakeVariableIgnoreMe;;
        esac
    done
}

prerequisites

Using Docker to Connect to Multiple VPN Networks Simultaneously (AKA Split Tunneling)

Like many of you, many people use Cisco AnyConnect to get on Enterprise Networks.

In my case, I had two separate Cisco AnyConnect networks that I needed to be connected to in order to be connected to a Virtual Desktop/Server through either RDP/SSH on each network.

As a result, I started digging into the IP Stack and seeing about ways to leverage Docker to segment route mapping and allow something like this to work to my advantage.

Here’s a rough sketch of what’s done here:

  • Step 1:
    • My Local Computer -> Spin Up Docker Container -> Have Docker Container Connect to Remote Cisco AnyConnect Endpoint
  • Step 2:
    • My Local Computer -> Allocate a local port and forward it to a remote address INSIDE the Docker Container (Destination IP/DNS and Port)
  • Step 3:
    • My Local Computer -> Open RDP/SSH Session on localhost and allocated local port -> Connection to Remote Desktop/Server Succeeded!

Now, I had a few issues getting this up and going and the major one was making sure that the OpenConnect/AnyConnect Client wasn’t effectively blocking out ssh connections to allow this port forward allocation. However, I DID end up finding a way around this and made sure that the OpenConnect/AnyConnect Client wasn’t hijacking all requests to port 22 and instead was only hijacking/redirecting requests to the VPN. I accomplished this by using a nifty tool called VPN Splice.

You can check out this awesome utility written by Dan Lenski here:

https://github.com/dlenski/vpn-slice

All in all I ended up with this great combo of work and I am extremely proud of it. It has to be the most complex little tool I think I have ever written and it would NOT be possible without the people over at Docker.

All of the below information and files can be found ready to go on my Github repo here:

https://github.com/qwertycody/Docker-VPN-Tool

Here is the Source Code (Future Updates will be on the Above Repo):

Filename: build.sh

docker rmi garrett_tech:vpn_tool --force
docker build --rm=true -t garrett_tech:vpn_tool .
docker system prune --force

Filename: Dockerfile

FROM debian:latest

RUN apt-get update 
RUN apt-get install -y openconnect
RUN apt-get install -y openssh-server 
RUN apt-get install -y passwd
RUN apt-get install -y python3
RUN apt-get install -y python3-pip
RUN apt-get install -y dnsutils
RUN apt-get install -y iptables
RUN apt-get install -y iproute2
RUN apt-get install -y screen

RUN pip3 install https://github.com/dlenski/vpn-slice/archive/master.zip

RUN apt-get clean all

RUN mkdir /var/run/sshd

RUN echo "PasswordAuthentication yes" >> /etc/ssh/ssh_config
RUN echo "PermitRootLogin yes" >> /etc/ssh/sshd_config

RUN echo 'echo "root:password" | chpasswd' >> /startup.sh
RUN echo "/usr/sbin/sshd -D &" >> /startup.sh
RUN echo "ping localhost" >> /startup.sh

EXPOSE 22
EXPOSE 3389

CMD sh /startup.sh

Filename: run_website.sh

OPENCONNECT_VPN_ENDPOINT="myCiscoVpnEndpoint.website.com"
DESTINATION_ADDRESS="myRemoteDesktopOrServerOrSshServer.website.com"
DESTINATION_PORT="3389"

LOCAL_DOCKER_ADDRESS="192.168.99.100"
LOCAL_DOCKER_SSH_PORT="2022"
LOCAL_LISTEN_PORT="2023"

CONTAINER_NAME="vpn_website"
IMAGE_NAME="garrett_tech:vpn_tool"

sh dockerVpnTool.sh $OPENCONNECT_VPN_ENDPOINT $DESTINATION_ADDRESS $DESTINATION_PORT $LOCAL_DOCKER_ADDRESS $LOCAL_DOCKER_SSH_PORT $LOCAL_LISTEN_PORT $CONTAINER_NAME $IMAGE_NAME

Filename: dockerVpnTool.sh

OPENCONNECT_VPN_ENDPOINT=$1
DESTINATION_ADDRESS=$2
DESTINATION_PORT=$3

LOCAL_DOCKER_ADDRESS=$4
LOCAL_DOCKER_SSH_PORT=$5
LOCAL_LISTEN_PORT=$6

CONTAINER_NAME=$7
IMAGE_NAME=$8

docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME

PORT_SSH="$LOCAL_DOCKER_SSH_PORT:22"

docker run -d --privileged --rm --name $CONTAINER_NAME -p $PORT_SSH $IMAGE_NAME

clear 

echo "##################################################################"
echo "THE NEXT PROMPT WILL ASK YOU TO ENTER A FEW THINGS"
echo "ONCE YOU ARE FULLY CONNECTED TO THE VPN ENDPOINT"
echo "PRESS CTRL+A+D TO DETACH AND CONTINUE THE CONNECTION PROCESS"
echo "IF YOU UNDERSTAND THESE INSTRUCTIONS PRESS ENTER TO CONTINUE"
echo "##################################################################"

read 

if [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ] || [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then
    winpty docker exec -it $CONTAINER_NAME bash -c "screen openconnect $OPENCONNECT_VPN_ENDPOINT --script \"vpn-slice $DESTINATION_ADDRESS\""
else 
    docker exec -it $CONTAINER_NAME bash -c "screen openconnect $OPENCONNECT_VPN_ENDPOINT --script \"vpn-slice $DESTINATION_ADDRESS\""
fi

ssh-keygen -R [$LOCAL_DOCKER_ADDRESS]:$LOCAL_DOCKER_SSH_PORT
ssh -fNL $LOCAL_LISTEN_PORT:$DESTINATION_ADDRESS:$DESTINATION_PORT -l root $LOCAL_DOCKER_ADDRESS -p $LOCAL_DOCKER_SSH_PORT

echo "##################################################################"
echo "If there are no errors up to this point you can now connect"
echo "to the endpoint using localhost:$LOCAL_LISTEN_PORT using ssh/rdp"
echo "##################################################################"

Automatic Bash Script for Unpackage/Repackage of Java WAR/JAR files

Had a need today to modify the contents of a WAR file and replace/update a specific XML file.

So you guessed it. I wrote a quick script for it.

Below are some usage screenshots:

Unpackaging a WAR:

Repackaging a WAR:


Here is the code:

unpackWar() {
    echo "Type Full Java JAR/WAR Path: "
	read FILE_PATH_FULL

    #echo "FILE_PATH_FULL:" 
    #echo $FILE_PATH_FULL

    FILE_EXTENSION=$(echo ${FILE_PATH_FULL##*.})

    #echo "FILE_EXTENSION:"
    #echo $FILE_EXTENSION

    FILE_NAME_WITHOUT_EXTENSION=$(basename "$FILE_PATH_FULL" ".$FILE_EXTENSION")

    #echo "FILE_NAME_WITHOUT_EXTENSION:"
    #echo $FILE_NAME_WITHOUT_EXTENSION

    FILE_NAME_WITH_EXTENSION="$FILE_NAME_WITHOUT_EXTENSION"
    FILE_NAME_WITH_EXTENSION+="."
    FILE_NAME_WITH_EXTENSION+="$FILE_EXTENSION"
    
    #echo "FILE_NAME_WITH_EXTENSION:"
    #echo $FILE_NAME_WITH_EXTENSION

    FILE_PATH_DIRECTORY=$(printf '%s\n' "${FILE_PATH_FULL//$FILE_NAME_WITH_EXTENSION/}")
    echo $FILE_PATH_DIRECTORY

    #echo "FILE_PATH_DIRECTORY:"
    #echo $FILE_PATH_DIRECTORY

    OUTPUT_DIRECTORY="$FILE_PATH_DIRECTORY/$FILE_NAME_WITHOUT_EXTENSION"

    #echo "OUTPUT_DIRECTORY:"
    #echo $OUTPUT_DIRECTORY

    OUTPUT_DIRECTORY_TEMP_FILE=$OUTPUT_DIRECTORY
    OUTPUT_DIRECTORY_TEMP_FILE+="/"
    OUTPUT_DIRECTORY_TEMP_FILE+=$FILE_NAME_WITH_EXTENSION

    #echo "OUTPUT_DIRECTORY_TEMP_FILE:"
    #echo $OUTPUT_DIRECTORY_TEMP_FILE

    mkdir "$OUTPUT_DIRECTORY"
    cp "$FILE_PATH_FULL" "$OUTPUT_DIRECTORY_TEMP_FILE"
    
    cd "$OUTPUT_DIRECTORY"
    jar -xf "$OUTPUT_DIRECTORY_TEMP_FILE" 
    rm "$OUTPUT_DIRECTORY_TEMP_FILE"
}

repackWar() {
    echo "Type Path To Package: "
	read OUTPUT_DIRECTORY

    echo "Type The Final File Extension (Without Period): "
	read FILE_EXTENSION

    FILE_NAME_WITH_EXTENSION=$(basename "$OUTPUT_DIRECTORY")
    FILE_NAME_WITH_EXTENSION+="."
    FILE_NAME_WITH_EXTENSION+=$FILE_EXTENSION
    
    cd "$OUTPUT_DIRECTORY"
    jar -cf "$FILE_NAME_WITH_EXTENSION" .
}

# Bash Menu Script Example
choiceFunction() {
	SUCCESS="false"

	while [ $SUCCESS == "false" ]
	do
		clear
		echo "Please enter your choice: "
		echo "1 - Unpackage War" 
		echo "2 - Repackage War" 
		echo "3 - Quit"
		read CHOICE

		case $CHOICE in
		   "1") SUCCESS="true";echo "Unpacking War ..."; unpackWar;;
		   "2") SUCCESS="true";echo "Packing War ..."; repackWar;;
		   "3") SUCCESS="true";echo "Exiting ..."; exit;;
		   *) read -p "Invalid choice, Press any key to continue..." fakeVariableIgnoreMe;;
		esac
	done
}

choiceFunction

Continuous Download Script Utilizing Bash

I had been having an issue getting a file from a central server halfway across the world and it kept failing every 5 minutes.

To remedy this I put a curl command inside a while loop and made it keep attempting to download the file until it successfully downloaded.

As a result, I came up with the below script, and it worked very nicely:

URL_TO_DOWNLOAD_FROM="http://URL.COM/download.zip"
FINAL_FILE_NAME="MyFile.zip"

EXIT_CODE=1

while [ $EXIT_CODE -ne 0 ]
do
	echo "Downloading File - $FINAL_FILE_NAME from $URL_TO_DOWNLOAD_FROM ..."
	rm -Rf $FINAL_FILE_NAME
	curl $URL_TO_DOWNLOAD_FROM --output $FINAL_FILE_NAME
	
	EXIT_CODE=$?
	
	if [ $EXIT_CODE -ne 0 ]; then
		echo "Download Failed! Retrying..."
	fi
done

if [ $EXIT_CODE -eq 0 ]; then
	echo "Download Finished!"
fi 

Automatic Connection Script for Cisco Any Connect and Windows RDP Box

Hello and welcome back!

Today I come to you with a quick hack I wrote to allow myself to quickly connect to Cisco Any Connect VPN Endpoints. I wrote this with Linux in mind as I use a local VirtualBox VM locally that runs literally nothing but a VPN and an RDP client.

The reason? I don’t want my main computer touching anything with this specific VPN I am referring to and wanted a flexible way to RDP into a required server.

As a result, I came up with the below script based off the current version of Cisco Any Connect in combination with xFreeRDP:

VPN_COMMAND="/opt/cisco/anyconnect/bin/vpn"
VPN_ADDRESS="https://corporate_vpn.com"
VPN_CONNECT="$VPN_COMMAND -s connect $VPN_ADDRESS"
VPN_DISCONNECT="$VPN_COMMAND disconnect"
USERNAME="username"
DOMAIN="domain"
PASSWORD="password"
VDI_ADDRESS="VDI-IP"
SUDO_PASSWORD="sudo_password"

$VPN_DISCONNECT

#Remove Existing Configurations
rm -f ~/.anyconnect
printf "$SUDO_PASSWORD" | sudo -S "find rm -f /opt/cisco/anyconnect/profile/ -name '*.xml' -delete"

echo "Type Token:"
read token

printf "y\ny\n" | $VPN_CONNECT
#$VPN_CONNECT

#If Certificate Not Trusted
printf "y\ny\n2\n$USERNAME\n$PASSWORD\n$token\n" | $VPN_CONNECT

#If Certificate Trusted
#printf "2\n$USERNAME\n$PASSWORD\n$token\n" | $VPN_CONNECT

xfreerdp /u:$DOMAIN\\$USERNAME /p:$PASSWORD /v:$VDI_ADDRESS /f -wallpaper +clipboard

Automatic Meeting Generator Using PowerShell (Generic and On-Boarding)

Today I come to you with a PowerShell Script written to generate meeting invites in mass quantity.

Here was the Problem Statement:

  • Problem:
    • I need to be able to generate (in-mass) meeting invites to a bunch of different people with various subjects
    • These meetings with the same people will 100% be needed to done again in the future so it needs to be automated
  • Solution:
    • Using the Outlook command-line extensions I can create a automated PowerShell script that can generate meetings in bulk

Here is the Code (Generic Version – Non On-Boarding):

$OUTLOOK = "C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE"

$MEETING_HASHMAP = @{ }

function generateParticipants {
    $PARTICIPANT_LIST = $args[0]

    $PARTICIPANT_STRING_TO_RETURN = ""

    foreach ($PARTICIPANT in $PARTICIPANT_LIST) {
        $PARTICIPANT_STRING_TO_RETURN = $PARTICIPANT_STRING_TO_RETURN + ";" +  $PARTICIPANT
    }

    return $PARTICIPANT_STRING_TO_RETURN
}

function createMeeting {
    
    $SUBJECT = $args[0]
        
    $BODY = $args[1]

    $PARTICIPANT_LIST = $args[2]

    $TO = generateParticipants $PARTICIPANT_LIST

    $MEETING_CONTENTS = "$TO&subject=$SUBJECT&body=$BODY"

    Start-Process -WindowStyle Maximized -FilePath "$OUTLOOK" -ArgumentList "/c ipm.appointment /m `"$MEETING_CONTENTS`""
}

function addMeeting {
    $SUBJECT_OF_MEETING = $args[0]
    $PARTICIPANT_LIST = $args[1]
    $MEETING_HASHMAP.Add($SUBJECT_OF_MEETING, $PARTICIPANT_LIST)
}

function generateMeetingInvites {
    foreach ($SUBJECT_OF_MEETING in $INTRODUCTION_HASHMAP.Keys) {
        $PARTICIPANT_LIST = $MEETING_HASHMAP[$SUBJECT_OF_MEETING]
        createMeeting $SUBJECT_OF_MEETING "Meeting Body" $PARTICIPANT_LIST
        Start-Sleep -Seconds 2
    }
}

$SUBJECT_OF_MEETING = "Quality Assurance"
$PARTICIPANT_LIST = New-Object Collections.Generic.List[String]
$PARTICIPANT_LIST.Add("bob.dole@company.com")
$PARTICIPANT_LIST.Add("jed.i.knighte@company.com")
addMeeting $SUBJECT_OF_MEETING $PARTICIPANT_LIST

$SUBJECT_OF_MEETING = "Software Development"
$PARTICIPANT_LIST = New-Object Collections.Generic.List[String]
$PARTICIPANT_LIST.Add("bob.dole@company.com")
$PARTICIPANT_LIST.Add("jed.i.knighte@company.com")
addMeeting $SUBJECT_OF_MEETING $PARTICIPANT_LIST

generateMeetingInvites

Here is the Other Code (On-Boarding Version):

$PERSON_NAME="Randy Pausch"
$PERSON_JOB_TITLE="Senior Imagineer"
$PERSON_EMAIL="randy.pausch@carnigie.edu"

$OUTLOOK = "C:\Program Files (x86)\Microsoft Office\root\Office16\OUTLOOK.EXE"

$INTRODUCTION_HASHMAP = @{ }

function generateSubject {
    $PERSON_JOB_TITLE = $args[0]
    $PERSON_NAME = $args[1]
    $DEPARTMENT_NAME = $args[2]

    return "Intro of New $PERSON_JOB_TITLE $PERSON_NAME to $DEPARTMENT_NAME"
}

function generateParticipants {
    $PARTICIPANT_LIST = $args[0]

    $PARTICIPANT_STRING_TO_RETURN = ""

    foreach ($PARTICIPANT in $PARTICIPANT_LIST) {
        $PARTICIPANT_STRING_TO_RETURN = $PARTICIPANT_STRING_TO_RETURN + ";" +  $PARTICIPANT
    }

    $PARTICIPANT_STRING_TO_RETURN = $PARTICIPANT_STRING_TO_RETURN + ";" + $PERSON_EMAIL

    return $PARTICIPANT_STRING_TO_RETURN
}

function createMeeting {
    $PERSON_JOB_TITLE = $args[0]
    
    $PERSON_NAME = $args[1]
    
    $DEPARTMENT_NAME = $args[2]
    
    $BODY = $args[3]
    
    $TO_ARRAY = $args[4]

    $SUBJECT = generateSubject $PERSON_JOB_TITLE $PERSON_NAME $DEPARTMENT_NAME

    $TO = generateParticipants $TO_ARRAY

    $MEETING_CONTENTS = "$TO&subject=$SUBJECT&body=$BODY"

    Start-Process -WindowStyle Maximized -FilePath "$OUTLOOK" -ArgumentList "/c ipm.appointment /m `"$MEETING_CONTENTS`""
}

function addDepartment {
    $DEPARTMENT_NAME = $args[0]
    $PARTICIPANT_LIST = $args[1]
    $INTRODUCTION_HASHMAP.Add($DEPARTMENT_NAME, $PARTICIPANT_LIST)
}

function generateMeetingInvites {
    foreach ($DEPARTMENT_NAME in $INTRODUCTION_HASHMAP.Keys) {
        createMeeting $PERSON_JOB_TITLE $PERSON_NAME $DEPARTMENT_NAME "Overview of Department and Practices" $INTRODUCTION_HASHMAP[$DEPARTMENT_NAME]
        Start-Sleep -Seconds 2
    }
}


$DEPARTMENT_NAME = "Quality Assurance"
$PARTICIPANT_LIST = New-Object Collections.Generic.List[String]
$PARTICIPANT_LIST.Add("bob.dole@company.com")
$PARTICIPANT_LIST.Add("jed.i.knighte@company.com")
addDepartment $DEPARTMENT_NAME $PARTICIPANT_LIST

$DEPARTMENT_NAME = "Software Development"
$PARTICIPANT_LIST = New-Object Collections.Generic.List[String]
$PARTICIPANT_LIST.Add("bob.dole@company.com")
$PARTICIPANT_LIST.Add("jed.i.knighte@company.com")
addDepartment $DEPARTMENT_NAME $PARTICIPANT_LIST

generateMeetingInvites