diff --git a/src/cmdUser/userAdd.go b/src/cmdUser/userAdd.go
index fc8f4f337383b4474ceb5b7d1a054a79f95a084c..7f7251e215b9182d62e3c549ba79efe3e0e96d78 100644
--- a/src/cmdUser/userAdd.go
+++ b/src/cmdUser/userAdd.go
@@ -80,7 +80,7 @@ func (cmd *Add)Run(args []string) int {
 		csvFile := args[0]
 		file, err := os.Open(csvFile)
 		if err != nil {
-			u.PrintlnErr("Failed opening \""+csvFile+"\" "+err.Error())
+			u.PrintlnErr("Error: "+err.Error())
 			return 1
 		}
 		defer file.Close()
@@ -93,13 +93,13 @@ func (cmd *Add)Run(args []string) int {
 				break
 			}
 			if err != nil {
-				u.PrintlnErr("Failed reading "+err.Error())
+				u.PrintlnErr("FAILED reading "+err.Error())
 				continue
 			}
 
 			columnCount := len(columns)
 			if columnCount < 5 {
-				u.PrintlnErr("Failed reading record on line ",line,": 5 columns are expected")
+				u.PrintlnErr("FAILED reading record on line ",line,": expecting 5 columns")
 				continue
 			}
 
@@ -118,7 +118,7 @@ func (cmd *Add)Run(args []string) int {
 			}
 
 			if err := cmd.runRequest(cargs); err != nil {
-				u.PrintlnErr("Failed creating user "+cargs.Email+": "+err.Error())
+				u.PrintlnErr("FAILED creating user "+cargs.Email+": "+err.Error())
 			} else {
 				u.Println("Successfully created user "+cargs.Email)
 			}
@@ -141,7 +141,6 @@ func (cmd *Add)runRequest(args *cmdArgs) error {
 	}
 
 	if resp.IsSuccess() {
-		u.Println(resp)
 		return nil
 	} else {
 		return errors.New("Error: "+resp.Status()+": "+resp.String())
diff --git a/src/cmdUser/userDel.go b/src/cmdUser/userDel.go
index 6306b2177e59247efc1b87955ea70e330877ed2a..ade8ba55e8ec473e3cb6a9a1403f4994eb4ab94f 100644
--- a/src/cmdUser/userDel.go
+++ b/src/cmdUser/userDel.go
@@ -1,6 +1,10 @@
 package cmdUser
 
 import (
+	"io"
+	"os"
+	"errors"
+	"encoding/csv"
 	u "nexus-client/utils"
 	g "nexus-client/globals"
 )
@@ -25,13 +29,12 @@ func (cmd *Del)PrintUsage() {
 	}
 	u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
 	u.PrintlnErr("USAGE: "+cmd.Name+" email [email ...]")
+	u.PrintlnErr("       "+cmd.Name+" file.csv")
 	u.PrintlnErr("―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――")
+	u.PrintlnErr("file.csv    1-column CSV file containing emails of users to delete.")
 }
 
 func (cmd *Del)Run(args []string) int {
-	client := g.GetInstance().Client
-	host := g.GetInstance().Host
-
 	argc := len(args)
 	if argc < 1 {
 		cmd.PrintUsage()
@@ -40,21 +43,80 @@ func (cmd *Del)Run(args []string) int {
 
 	statusCode := 0
 
-	// Iterates through each user (email) to delete
-	for i:= range(args) {
-		email := args[i]
-		resp, err := client.R().Delete(host+"/users/"+email)
+	if argc == 1 && !u.IsEmail(args[0]) {
+		// Single argument and it's a CSV file
+		csvFile := args[0]
+
+		if u.IsEmail(csvFile) {
+			cmd.PrintUsage()
+			return 1
+		}
+
+		file, err := os.Open(csvFile)
 		if err != nil {
 			u.PrintlnErr("Error: "+err.Error())
-			statusCode = 1
-		} else {
-			if resp.IsSuccess() {
-				u.Println("User "+email+" deleted.")
+			return 1
+		}
+		defer file.Close()
+		reader := csv.NewReader(file)
+		line := 0
+		for {
+			line += 1
+			columns, err := reader.Read()
+			if err == io.EOF {
+				break
+			}
+			if err != nil {
+				u.PrintlnErr("FAILED reading "+err.Error())
+				statusCode = 1
+				continue
+			}
+
+			columnCount := len(columns)
+			if columnCount != 1 {
+				u.PrintlnErr("FAILED reading record on line ",line,": expecting 1 column")
+				statusCode = 1
+				continue
+			}
+
+			email := columns[0]
+			if err := cmd.runRequest(email); err != nil {
+				u.PrintlnErr(err.Error())
+				statusCode = 1
 			} else {
-				u.PrintlnErr("Error: "+resp.Status()+": "+resp.String())
+				u.Println("Successfully deleted user "+email)
+			}
+		}
+	} else {
+		// Argument(s) is/are email addresses
+
+		// Iterates through each user (email) to delete
+		for i:= range(args) {
+			email := args[i]
+			if err := cmd.runRequest(email); err != nil {
+				u.PrintlnErr(err.Error())
 				statusCode = 1
+			} else {
+				u.Println("Successfully deleted user "+email)
 			}
 		}
 	}
+
 	return statusCode
 }
+
+func (cmd *Del)runRequest(email string) error {
+	client := g.GetInstance().Client
+	host := g.GetInstance().Host
+
+	resp, err := client.R().Delete(host+"/users/"+email)
+	if err != nil {
+		return errors.New("Error: "+err.Error())
+	}
+
+	if resp.IsSuccess() {
+		return nil
+	} else {
+		return errors.New("Error: "+resp.Status()+": "+resp.String())
+	}
+}
diff --git a/src/cmdVM/vmCreate.go b/src/cmdVM/vmCreate.go
index bfd6c6b93d7037defacf4bc967b1e754c3cff978..80bd2602cdb0be99aea13039031e677dc1ed3270 100644
--- a/src/cmdVM/vmCreate.go
+++ b/src/cmdVM/vmCreate.go
@@ -36,7 +36,7 @@ template    ID of the template to VM will be based on.
 count       Number of VMs to create (if not specified, one is created).
             If specified and > 1, each VM's name is postfixed with [n],
             where n ranges from 1..count.
-file.csv    Single-column CSV file defining the students names.
+file.csv    1-column CSV file defining the students names.
             Each VM's name is postfixed with each entry in the CSV file.`
 	u.PrintlnErr(usage)
 }
@@ -71,10 +71,9 @@ func (cmd *Create)Run(args []string) int {
 	if argc == 6 {
 		count, err = strconv.Atoi(args[5])
 		if err != nil {
-			// It's not a number, so we assume it's a CSV file.
-			// Checks if the file exists.
-			file := args[5]
-			csvEntries, err = u.ReadCSVColumn(file, 0)
+			// It's not a number, we assume it's a CSV file and parse it.
+			csvFile := args[5]
+			csvEntries, err = u.ReadCSVColumn(csvFile, 0)
 			if err != nil {
 				u.PrintlnErr(err.Error())
 				return 1
diff --git a/src/utils/csv.go b/src/utils/csv.go
index 44c832e3c08dea49dac8ab592134631681ee95e9..6c98c164795cc957b9dc13c622cad923bb78b014 100644
--- a/src/utils/csv.go
+++ b/src/utils/csv.go
@@ -12,7 +12,7 @@ import (
 func ReadCSVColumn(csvFile string, column int) ([]string, error) {
 	file, err := os.Open(csvFile)
     if err != nil {
-        return nil, errors.New("Failed opening \""+csvFile+"\"")
+        return nil, errors.New("Error: "+err.Error())
     }
 	defer file.Close()
     reader := csv.NewReader(file)
@@ -24,7 +24,7 @@ func ReadCSVColumn(csvFile string, column int) ([]string, error) {
 			break
 		}
 		if err != nil {
-			return nil, errors.New("Failed reading \""+csvFile+"\"")
+			return nil, errors.New("Failed reading "+err.Error())
 		}
 		if column >= len(record) {
 			return nil, errors.New("Failed reading \""+csvFile+"\": column out of bound")
diff --git a/src/utils/utils.go b/src/utils/utils.go
index 017661182a56b234f96d18524b9fc9d66d133a67..1c09b93add95866eb18e0f8260e42b9919320ffa 100644
--- a/src/utils/utils.go
+++ b/src/utils/utils.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"bytes"
 	"errors"
+	"net/mail"
 	"archive/tar"
 	"path/filepath"
 	"compress/gzip"
@@ -98,4 +99,9 @@ func GetRandomTempFilename() (string, error) {
 	}
 	randName := "temp_"+uuid.String()
 	return filepath.Join(tempDir, randName), nil
-}
\ No newline at end of file
+}
+
+func IsEmail(email string) bool {
+    _, err := mail.ParseAddress(email)
+	return err == nil
+}
diff --git a/src/version/version.go b/src/version/version.go
index 4e09f458aa411ead435ec642a0a99947c6f5d74e..4157545f4716e07195168b8f3b9da391d9bf31a6 100644
--- a/src/version/version.go
+++ b/src/version/version.go
@@ -8,7 +8,7 @@ import (
 const (
 	major  = 1
 	minor  = 4
-	bugfix = 0
+	bugfix = 1
 )
 
 type Version struct {