Esempio n. 1
0
if True:  # open hosts file, get backups and copy to backup server
    # hosts.csv containing device type, hostname, ip, username and password
    with open('hosts.csv') as csvfile:
        read_csv = csv.reader(csvfile, delimiter=',')
        for row in read_csv:
            if row[0] == 'F5' and row[7] == 'Yes':
                backup_file = open(f'F5-Backup_{row[1]}_{date_format}.txt',
                                   'w+')
                backup = Connect(row[1], row[2], row[3], row[4])
                backup = backup.decode('utf-8')
                for l in backup:
                    backup_file.write(l)
                ucs_filename = SCP(row[1], row[2], row[3], row[4])
                ucs_filename = str(ucs_filename)
                backup_server_client.copy(
                    f"F5-Backup_{row[1]}_{date_format}.txt",
                    f"{backup_drive}\\F5-Backup_{row[1]}_{date_format}.txt")
                backup_server_client.copy(
                    f"{ucs_filename}", f"{backup_drive}\\UCS\\{ucs_filename}")
                backup_file.close()
                remove_file1 = subprocess.Popen(
                    f'rm F5-Backup_{row[1]}_{date_format}.txt',
                    stdout=subprocess.PIPE,
                    shell=True)
                remove_file1.communicate()
                remove_file2 = subprocess.Popen(f'rm {ucs_filename}',
                                                stdout=subprocess.PIPE,
                                                shell=True)
                remove_file2.communicate()
if True:  # remove temp files and exit script
    remove_csv = subprocess.Popen(f'rm hosts.csv',
Esempio n. 2
0
class Dns():
    def __init__(self, dns_svr, user, password, csv_dns_dm):
        self.dns_svr = dns_svr
        self.user = user
        self.password = password
        self.csv_dns_fw_dm = csv_dns_dm[0]
        self.csv_dns_rv_dm = csv_dns_dm[1]

        # WSman connection used to run powershell cmds on windows servers
        self.wsman_conn = WSMan(self.dns_svr, username=self.user, password=self.password, ssl=False)
        self.client_conn = Client(self.dns_svr, username=self.user, password=self.password, ssl=False)

###################################### FAILFAST ######################################
    # Check if zones exist on DNS server
    def failfast(self):
        all_zones, bad_zones = ([] for i in range(2))
        # Create combined list of all forward and reverse zones
        for csv_dict in self.csv_dns_fw_dm:
            for zone in csv_dict.keys():
                all_zones.append(zone)
        for csv_dict in self.csv_dns_rv_dm:
            for zone in csv_dict.keys():
                all_zones.append(zone)

    # Interate through all zones and see if exist on DNS server
        for zone in all_zones:
            with RunspacePool(self.wsman_conn) as pool:
                print('-', zone)
                ps = PowerShell(pool)
                # The powershell cmd is "Get-DhcpServerv4Reservation -scopeid 192.168.200.0"
                ps.add_cmdlet("Invoke-Expression").add_parameter("Command", "Get-DnsServerZone {}".format(zone))
                ps.add_cmdlet("Out-String").add_parameter("Stream")
                ps.invoke()
                dns_zones = ps.output

            if len(dns_zones) == 0:
                bad_zones.append(zone)
        # If any of the scopes dont not exist values are returned to main.py (which also casues script to exit)
        if len(bad_zones) != 0:
            return '!!! Error - The following zones dont exist on the DNS server: \n{}'.format(bad_zones)

###################################### Get DNS reservations ######################################
    def get_entries(self):
        dns_fw_dm, dns_rv_dm = ([] for i in range(2))

        # On a per-zone basis gets all the current DNS entries that will then be compared to those in the CSV
        for csv_dns_fw in self.csv_dns_fw_dm :
            for domain in csv_dns_fw.keys():
                with RunspacePool(self.wsman_conn) as pool:
                    ps = PowerShell(pool)
                    # The powershell cmd is "Get-DnsServerResourceRecord -ZoneName stesworld.com -RRType A"
                    ps.add_cmdlet("Invoke-Expression").add_parameter("Command", "Get-DnsServerResourceRecord -ZoneName {} -RRType A".format(domain))
                    ps.add_cmdlet("Out-String").add_parameter("Stream")
                    ps.invoke()
                    dns_fw_records = ps.output

                # From the ps output create a list for the dns_fw DM dict value [('ip', 'name', ttl)]
                ip_name_ttl = []
                if len(dns_fw_records) == 0:                # skips if no A records in the zone
                    pass
                else:
                    for a in dns_fw_records[3:-2]:          # Elimates headers and trailing blank lines
                        a = a.split()
                        ip_name_ttl .append((a[-1], a[0].lower(), a[-2]))
                    # Add the list as the value for for a dict where the zone name is the key [{fw_zone: [(ip, name, ttl)]}]
                    dns_fw_dm.append({domain: ip_name_ttl})

        # On a per-reverse-zone basis gets all the current DNS entries that will then be compared to those in the CSV
        for csv_dns_rv in self.csv_dns_rv_dm:
            for rev_zone in csv_dns_rv.keys():
                with RunspacePool(self.wsman_conn) as pool:
                    ps = PowerShell(pool)
                    ps.add_cmdlet("Invoke-Expression").add_parameter("Command", "Get-DnsServerResourceRecord -ZoneName {} -RRType PTR".format(rev_zone))
                    ps.add_cmdlet("Out-String").add_parameter("Stream")
                    ps.invoke()
                    dns_rv_records = ps.output

                hst_name = []
                if len(dns_rv_records) == 0:    # skips if no PTR records in the zone
                    pass
                else:
                    for ptr in dns_rv_records[3:-2]:
                        ptr = ptr.split()
                        hst_name.append((ptr[0], ptr[-1].lower()))
                dns_rv_dm.append({rev_zone: hst_name})      # creates DM where rv_zone name is the key [{rv_zone: [(host, domain_name)]}]

        return [dns_fw_dm, dns_rv_dm]

###################################### Compare new Vs current resv ######################################
    def verify_csv_vs_svr(self, dns_dm):
        dns_fw_dm = dns_dm[0]
        dns_rv_dm = dns_dm[1]

        csv_name, csv_rv_name, dns_fw_name, dns_rv_name, used_fw_fqdn, used_rv_fqdn = ([] for i in range(6))
        # Create a list tuples of all FQDNs from CSV DMs (zone, fqdn)
        for dict_domain in self.csv_dns_fw_dm:
            domain = '.' + list(dict_domain.keys())[0]
            for all_values in dict_domain.values():
                for each_value in all_values:
                    csv_name.append((list(dict_domain.keys())[0], each_value[1] + domain))
        for dict_domain in self.csv_dns_rv_dm:
            for all_values in dict_domain.values():
                for each_value in all_values:
                    csv_rv_name.append((list(dict_domain.keys())[0], each_value[1]))

        # Create a list tuples of all FQDNs from DNS DMs (zone, fqdn)
        for dict_domain in dns_fw_dm:
            domain = '.' + list(dict_domain.keys())[0]
            for all_values in dict_domain.values():
                for each_value in all_values:
                    dns_fw_name.append((list(dict_domain.keys())[0], each_value[1] + domain))
        for dict_domain in dns_rv_dm:
            for all_values in dict_domain.values():
                for each_value in all_values:
                    dns_rv_name.append((list(dict_domain.keys())[0], each_value[1]))

        # Create list of any already used FQDNs in DNS by removing any unique values
        used_fw_fqdn = set(csv_name) & set(dns_fw_name)
        used_rv_fqdn = set(csv_rv_name) & set(dns_rv_name)
        used_fqdn = sorted(list(used_fw_fqdn)) + sorted(list(used_rv_fqdn))

        # Compares FQDNs in CSV to FQDNs on DNS server, will list any in the CSV that are missing from DNS server
        missing_fw_fqdn = set(csv_name) - set(dns_fw_name)
        missing_rv_fqdn = set(csv_rv_name) - set(dns_rv_name)
        missing_fqdn = sorted(list(missing_fw_fqdn)) + sorted(list(missing_rv_fqdn))

        # What is returned to main.py to kill script if any duplicates. len(csv_name) is used to compare pre and post number of entries
        len_csv = str(len(dns_fw_name)) + '/' + str(len(dns_rv_name))       # Number of added records in the format A/PTR
        output = {'len_csv': len_csv, 'used_entries': used_fqdn, 'missing_entries': missing_fqdn}
        return output

###################################### Creates new CSV with no scope prefix  ######################################
    def create_new_csv(self, type, csv_file, temp_csv):
        self.num_new_entries = 0
        # Creates a temp csv file with header and format compatible with DNS server import.
        if type == 'add':
            with open(temp_csv, 'w') as x:
                writer = csv.writer(x)
                writer.writerow(['ZoneName','Name','IPAddress','TimeToLive'])
                for dict_domain in self.csv_dns_fw_dm:
                    domain = list(dict_domain.keys())[0]
                    for all_values in dict_domain.values():
                        for each_value in all_values:
                            self.num_new_entries += 1                 # Number of reservatiosn to be added
                            writer.writerow([domain,each_value[1],each_value[0],each_value[2]])
        # Dont add header on these as windows ps cmd wont understand 'ZoneName', luckily can do on position number so no need for header.
        elif type == 'remove':
            self.temp_csv1 = temp_csv.replace(".csv", "1.csv")              # Extra temp file required for removing DNS RV entries
            with open(temp_csv, 'w') as x:
                writer = csv.writer(x)
                writer.writerow(['ZoneName','Name', 'RRType'])
                for dict_domain in self.csv_dns_fw_dm:
                    domain = list(dict_domain.keys())[0]
                    for all_values in dict_domain.values():
                        for each_value in all_values:
                            self.num_new_entries += 1                 # Number of reservatiosn to be added
                            writer.writerow([domain,each_value[1],'A'])
            with open(self.temp_csv1, 'w') as x:
                writer = csv.writer(x)
                writer.writerow(['ZoneName','Name', 'RRType'])
                for dict_domain in self.csv_dns_rv_dm:
                    domain = list(dict_domain.keys())[0]
                    for all_values in dict_domain.values():
                        for each_value in all_values:
                            writer.writerow([domain,each_value[0],'PTR'])

        # Used only with pytest to test new CSV file created and the contents are correct
        pytest_csv = []
        with open(temp_csv, 'r') as x:
            csv_read = csv.reader(x)
            for row in csv_read:
                pytest_csv.append(row)
        if type == 'remove':             # To test both CSVs if remove
            pytest_csv1 = []
            with open(self.temp_csv1, 'r') as x:
                csv_read = csv.reader(x)
                for row in csv_read:
                    pytest_csv1.append(row)
            return [pytest_csv, pytest_csv1]
        else:
            return pytest_csv

###################################### Adds or Removes the DHCP reservations ######################################
    def deploy_csv(self, type, temp_csv, win_dir):
        win_dir1 = win_dir.replace(".csv", "1.csv")              # Extra temp file required for removing DNS RV entries
        self.num_new_entries = str(self.num_new_entries) + '/' + str(self.num_new_entries)      # To make it A/PTR records, should be same as deployed in the 1 cmd
        # Copy the new CSV File onto DHCP server, script will fail if it cant
        try:
            self.client_conn.copy(temp_csv, win_dir)
            if type == 'remove':
                self.client_conn.copy(self.temp_csv1, win_dir1)
        except Exception as e:              # If copy fails script fails
            print("!!! Error - Could not copy CSV file to DNS server, investigate the below error before re-running the script.\n{}".format(e))
            exit()

        # Add DNS entries
        if type == 'add':
            with RunspacePool(self.wsman_conn) as pool:
                ps = PowerShell(pool)
                ps.add_cmdlet("Import-Csv").add_argument("{}".format(win_dir)).add_cmdlet("Add-DNSServerResourceRecordA").add_parameter("-CreatePtr")
                ps.invoke()
            output = [self.num_new_entries, [ps.had_errors], [ps.streams.error]]

        # Remove DNS entries, have to spilt into multiple cmds due to bug with "Remove-DNSServerResourceRecord" where cant use RRtype from CSV
        elif type == 'remove':
            with RunspacePool(self.wsman_conn) as pool:
                ps = PowerShell(pool)
                ps.add_cmdlet("Import-Csv").add_argument("{}".format(win_dir)).add_cmdlet("Remove-DNSServerResourceRecord").add_parameter("RRtype", "A").add_parameter("-Force")
                ps.invoke()
            output = [self.num_new_entries, [ps.had_errors], [ps.streams.error]]      # adds the errors as lists so can add outputs from next cmd
            with RunspacePool(self.wsman_conn) as pool:
                ps = PowerShell(pool)
                ps.add_cmdlet("Import-Csv").add_argument("{}".format(win_dir1)).add_cmdlet("Remove-DNSServerResourceRecord").add_parameter("RRtype", "PTR").add_parameter("-Force")
                ps.invoke()
            output[1].append(ps.had_errors)
            output[2].append(ps.streams.error)

        # Cleanup temp files
        try:
            os.remove(temp_csv)
            self.client_conn.execute_cmd("del {}".format(win_dir.replace("/", "\\")))      # Windows wont take / format with the cmd
            if type == 'remove':
                os.remove(self.temp_csv1)
                self.client_conn.execute_cmd("del {}".format(win_dir1.replace("/", "\\")))      # Windows wont take / format with the cmd
        except Exception as e:              # If delete fails warns user
            print("!!! Warning - Could not delete temporary files off DNS server, you will have to do manually.\n{}".format(e))

        return output
    import pypsrp
    from pypsrp.client import Client
if True:  # set global variables
    now = datetime.datetime.now()
    month = '{:02d}'.format(now.month)
    day = '{:02d}'.format(now.day)
    device_hostname = '''+DEVICE HOSTNAME HERE+'''
    user = r'''+MS CA USERNAME WITH DOMAIN HERE+'''
    pwd = '''+MS CA PASSWORD HERE+'''
    ca = '''+MS CA IP OR RESOLVABLE HOSTNAME HERE+'''
    date_format = f'{now.year}{month}{day}'
    csrname = f'{device_hostname}_{now.year}{month}{day}.txt'
    ca_drive = r'''+PATH TO DRIVE WHERE CERTIFICATES ARE MANAGED ON MS CA HERE+'''
    submit_command = 'certreq.exe -submit -config -'
    certname = f'{now.year}{month}{day}.cer'
if True:  # set pypsrp client connection settings to CA
    ca_client = Client(f"{ca}",
                       username=f"{user}",
                       password=pwd,
                       cert_validation=False,
                       ssl=False)
if True:  # copy csr to CA with pypsrp client
    # !!!applicable csr must be present in directory where this is run!!!
    ca_client.copy(csrname, f"{ca_drive}\\{csrname}")
if True:  # 'submit'/sign csr on CA with pypsrp client
    ca_client.execute_cmd(
        f'{submit_command} {ca_drive}\\{csrname} {ca_drive}\\{certname}')
if True:  # fetch cert from CA
    # !!!will put certificate in directory where this is run!!!
    ca_client.fetch(f"{ca_drive}\\{certname}", certname)
Esempio n. 4
0
import os
from pypsrp.client import Client

username = os.environ["ANSIBLE_WIN_USER"]
password = os.environ["ANSIBLE_WIN_PASSWORD"]
print(username)
print(password)

# this takes in the same kwargs as the WSMan object
client = Client("localhost", port=5985, ssl=False, cert_validation=False, username=username, password=password)
# execute a cmd command
stdout, stderr, rc = client.execute_cmd("dir")
print(stdout)
stdout, stderr, rc = client.execute_cmd("powershell.exe gci $pwd")
print(stderr)

exit()

sanitised_stderr = client.sanitise_clixml(stderr)
# execute a PowerShell script
output, streams, had_errors = client.execute_ps('''$path = "%s"
if (Test-Path -Path $path) {
    Remove-Item -Path $path -Force -Recurse
}
New-Item -Path $path -ItemType Directory''' % path)
output, streams, had_errors = client.execute_ps("New-Item -Path C:\\temp\\folder -ItemType Directory")
# copy a file from the local host to the remote host
client.copy("~/file.txt", "C:\\temp\\file.txt")
# fetch a file from the remote host to the local host
client.fetch("C:\\temp\\file.txt", "~/file.txt")
Esempio n. 5
0
    async def exec_powershell_script_dependencies(self, hosts, shell_type,
                                                  arguments, dependency_folder,
                                                  destination_folder, username,
                                                  password, transport,
                                                  server_cert_validation,
                                                  message_encryption):
        """
        Execute a list of remote commands on a list of hosts.
        :param hosts: List of host ips to run command on
        :param shell_type: The type of shell you wish to run (i.e. "powershell")
        :param commands: array of commands in which you want to run on every host
        :param dependency_folder: Specifies the local folder to copy
        :param destination_folder: Specifies the destination folder to copy and delete
        :param username: username of the machine you wish to run command on
        :param password: password for the machine you wish to run command on
        :param transport: method of transportation
        :param server_cert_validation: whether or not to verify certificates
        :param message_encryption: When you should encrypt messages

        :return: dict of results with hosts as keys and list of outputs for each specified hosts
        """
        results = {}

        for host in hosts:
            self.logger.info(f"Connecting to {host}")
            results[host] = []

            try:
                wsman = WSMan(host,
                              ssl=server_cert_validation,
                              auth=transport,
                              encryption=message_encryption,
                              username=username,
                              password=password)
                client = Client(host,
                                ssl=server_cert_validation,
                                auth=transport,
                                encryption=message_encryption,
                                username=username,
                                password=password)

                self.logger.info(f"Copying to {host}")
                for root, dirs, files in os.walk(dependency_folder):
                    root_folder = destination_folder + "\\" + os.path.basename(
                        root)
                    output, streams, had_errors = client.execute_ps('''
                        $path = "%s"

                        if(!(Test-Path -Path $path )){
                            New-Item -ItemType directory -Path $path
                            Write-Host "New folder created"
                        }''' % root_folder)

                    results[host].append({
                        "stdout": output,
                        "had_errors": had_errors
                    })
                    for file in files:
                        client.copy(os.path.join(root, file),
                                    root_folder + "\\" + file)

                self.logger.info(f"Executing on {host}")

                # execute scripts
                with WinRS(wsman) as shell:
                    #Changes directory to dependency root and appends folder removal to end
                    arguments = f"cd {destination_folder};" + '; '.join(
                        arguments)
                    self.logger.info(f"{arguments}")
                    process = Process(shell, shell_type, [arguments])
                    process.invoke()
                    results[host].append({
                        "stdout": process.stdout.decode(),
                        "stderr": process.stderr.decode()
                    })

                    arguments = f"Remove-Item -Recurse {destination_folder}"
                    self.logger.info(f"Removing from {host}")
                    process = Process(shell, shell_type, [arguments])
                    process.invoke()
                    process.signal(SignalCode.CTRL_C)

            except Exception as e:
                import traceback
                tb = traceback.format_exc()
                results[host].append({
                    "stdout": "",
                    "stderr": f"{e}",
                    "exception": f"{tb}"
                })

        return results
Esempio n. 6
0
class Dhcp():
    def __init__(self, dhcp_svr, user, password, csv_dhcp_dm):
        self.dhcp_svr = dhcp_svr
        self.user = user
        self.password = password
        self.csv_dhcp_dm = csv_dhcp_dm

        # WSman connection used to run powershell cmds on windows servers
        self.wsman_conn = WSMan(self.dhcp_svr,
                                username=self.user,
                                password=self.password,
                                ssl=False)
        self.client_conn = Client(self.dhcp_svr,
                                  username=self.user,
                                  password=self.password,
                                  ssl=False)

###################################### FAILFAST ######################################
# Check if scopes exist on DHCP server

    def failfast(self):
        bad_scopes = []
        for csv_dict in self.csv_dhcp_dm:
            for scope in csv_dict.keys():
                print('-', scope)
                # Get list of all reservations in the scope
                with RunspacePool(self.wsman_conn) as pool:
                    ps = PowerShell(pool)
                    # The powershell cmd is "Get-DhcpServerv4Reservation -scopeid 192.168.200.0"
                    ps.add_cmdlet("Invoke-Expression").add_parameter(
                        "Command",
                        "Get-DhcpServerv4Scope -scopeid {}".format(scope))
                    ps.add_cmdlet("Out-String").add_parameter("Stream")
                    ps.invoke()
                    dhcp_reserv = ps.output

                if len(dhcp_reserv) == 0:
                    bad_scopes.append(scope)
        # If any of the scopes dont not exist values are returned to main.py (which also casues script to exit)
        if len(bad_scopes) != 0:
            return '!!! Error - The following scopes dont exist on the DHCP server: \n{}'.format(
                bad_scopes)

###################################### Get DHCP reservations ######################################

    def get_entries(self):
        dhcp_dm = []
        # On a per-scope gets all the current DHCP addresses that will then be compared to those in the CSV
        for csv_dict in self.csv_dhcp_dm:
            for scope in csv_dict.keys():
                # Get list of all reservations in the scope
                with RunspacePool(self.wsman_conn) as pool:
                    ps = PowerShell(pool)
                    # The powershell cmd is "Get-DhcpServerv4Reservation -scopeid 192.168.200.0"
                    ps.add_cmdlet("Invoke-Expression").add_parameter(
                        "Command",
                        "Get-DhcpServerv4Reservation -scopeid {}".format(
                            scope))
                    ps.add_cmdlet("Out-String").add_parameter("Stream")
                    ps.invoke()
                    dhcp_reserv = ps.output[
                        3:-2]  # Elimates headers and blank lines

                # From the ps output create a DHCP DM of scope: [[IP], [mac], [name], [(IP, MAC, name)]]
                ip_name_mac = []
                if len(dhcp_reserv
                       ) == 0:  # skips if no DHCP reservations in the scope
                    pass
                else:
                    for r in dhcp_reserv:
                        ip_name_mac.append(
                            (r.split()[0], r.split()[3][:17].lower(),
                             r.split()[2].lower()))
                    dhcp_dm.append({scope: ip_name_mac})
        return dhcp_dm

###################################### Compare new Vs current resv ######################################

    def verify_csv_vs_svr(self, dhcp_dm):
        csv_ip, csv_name, csv_mac, dhcp_ip, dhcp_name, dhcp_mac, dhcp_ip_name_mac = (
            [] for i in range(7))
        #Create a list of IPs, domain names and MACs from each DM (CSV and from dhcp_srv)
        for dict_scope in self.csv_dhcp_dm:
            for all_values in dict_scope.values():
                for each_value in all_values:
                    csv_ip.append(each_value[0])
                    csv_name.append(
                        each_value[1][:17]
                    )  # Needed as windows limits name returned to 17 characters
                    csv_mac.append(each_value[2])
        for dict_scope in dhcp_dm:
            for all_values in dict_scope.values():
                for each_value in all_values:
                    dhcp_ip.append(each_value[0])
                    dhcp_name.append(each_value[1])
                    dhcp_mac.append(each_value[2])
                    dhcp_ip_name_mac.append(
                        each_value)  # Used in user output if conflicts

        # Create list of any already used IPs, names or macs in reservations by removing any unique values
        used_ipadd = set(csv_ip) & set(dhcp_ip)
        used_name = set(csv_name) & set(dhcp_name)
        used_mac = set(dhcp_mac) & set(csv_mac)

        # Creates a list of all used reservations by finding it based on IP, name and mac in original DHCP reservations variable
        list_from_ip, list_from_name, list_from_mac = ([] for i in range(3))
        if used_ipadd != 0:
            for x in used_ipadd:
                for y in dhcp_ip_name_mac:
                    if x == y[0]:
                        list_from_ip.append(y)
        if used_name != 0:
            for x in used_name:
                for y in dhcp_ip_name_mac:
                    if x == y[1]:
                        list_from_name.append(y)
        if used_mac != 0:
            for x in used_mac:
                for y in dhcp_ip_name_mac:
                    if x == y[2]:
                        list_from_mac.append(y)
        # Creates a final list of used reservations removing any duplicates from the ip, name and mac lists
        used_reserv = set(list_from_ip) | set(list_from_name) | set(
            list_from_mac)
        # Compares IPs in CSV to IPs on DHCP server, will list any in the CSV that are missing from DHCP server
        missing_resv = set(csv_ip) - set(dhcp_ip)

        # What is returned to main.py to kill script if any duplicates. len(csv_name) is used to compare pre and post number of entries
        output = {
            'len_csv': len(dhcp_ip_name_mac),
            'used_entries': sorted(list(used_reserv)),
            'missing_entries': sorted(list(missing_resv))
        }
        return output

###################################### Creates new CSV with no scope prefix  ######################################

    def create_new_csv(self, type, csv_file, temp_csv):
        # # Creates a new list from the CSV with prefix removed from the scope
        new_csv = []
        with open(csv_file, 'r') as x:
            csv_read = csv.reader(x)
            for row in csv_read:
                if len(row) == 0 or all(
                        0 == len(s) for s in row
                ):  #If it is a blank line skips or all blank columns
                    continue
                else:
                    row[0] = (row[0].split('/')[0]
                              )  # Removes prefix from the scope
                    new_csv.append(row)
        self.num_new_entries = len(
            new_csv) - 1  # Number of reservatiosn to be added
        # Writes the new list to a temp csv file
        with open(temp_csv, 'w') as x:
            writer = csv.writer(x)
            for row in new_csv:
                writer.writerow(row)

        # Used only with pytest to test new CSV file created and the contents are correct
        pytest_csv = []
        with open(temp_csv, 'r') as x:
            csv_read = csv.reader(x)
            for row in csv_read:
                pytest_csv.append(row)
        return pytest_csv

###################################### Adds or Removes the DHCP reservations ######################################

    def deploy_csv(self, type, temp_csv, win_dir):
        # Copy the new CSV File onto DHCP server, script will fail if it cant
        try:
            self.client_conn.copy(temp_csv, win_dir)
        except Exception as e:  # If copy fails script fails
            print(
                "!!! Error - Could not copy CSV file to DHCP server, investigate the below error before re-running the script.\n{}"
                .format(e))
            exit()

        # Add or remove DHCP entries dependant on the value of the variable 'type'
        with RunspacePool(self.wsman_conn) as pool:
            ps = PowerShell(pool)
            if type == 'add':
                ps.add_cmdlet("Import-Csv").add_argument("{}".format(
                    win_dir)).add_cmdlet("Add-DhcpServerv4Reservation")
            elif type == 'remove':
                ps.add_cmdlet("Import-Csv").add_argument("{}".format(
                    win_dir)).add_cmdlet("Remove-DhcpServerv4Reservation")
            ps.invoke()
        output = [self.num_new_entries, [ps.had_errors], [ps.streams.error]]

        # Cleanup temp files
        os.remove(temp_csv)
        try:
            self.client_conn.execute_cmd("del {}".format(
                win_dir.replace(
                    "/", "\\")))  # Windows wont take / format with the cmd
        except Exception as e:  # If delete fails warns user
            print(
                "!!! Warning - Could not delete temporary file {} off DHCP server, you will have to do manually.\n{}"
                .format(win_dir, e))

        return output