Windows 下指令碼遠端管理數百台蘋果系統

來源:互聯網
上載者:User

標籤:powershell   python   遠端管理   linux   osx   

問題

今天同事的AD帳號頻繁被鎖,在DC的日誌上顯示源於無線網ISE的驗證失敗,ISE伺服器的日誌顯示某個IP的裝置的AD密碼錯誤。

我把無線AP所在的範圍,這個裝置的Mac地址給同事,問題來了,他轉了半個小時,愣是找不到對應的裝置,也沒有人報告連網不通。這個就很尷尬了~~

思路

怎麼找到對應的裝置呢,因為無線網AD驗證沒通過,DHCP伺服器沒有任何記錄。很多人同時開啟WiFi和有線網,也許我可以通過有線網去找這個無線網卡的地址。

豆子想了一個笨辦法,首先通過Mac地址可以判斷出這個是蘋果的網卡,那麼我遠程連到所有的蘋果系統上查詢對應的網卡應該有可能擷取到這個地址。

想到了就做做吧。

純屬練手,我用Python和Powershell都試了試。

Python 指令碼

Python我曾經寫過一個模仿fabric的程式,可以遠端對多台Linux或者OSX機器執行遠程操作,上傳和下載。基本上就是調用threading, paramiko,queue幾個模組。

#!/usr/bin/env python# -*- coding:utf-8 -*-# Author Yuan Li""" 本程式類比Fabric,遠端批量進行SSH串連,可以執行下載,上傳和shell命令執行。 遠程命令的執行,使用了線程池的技術,因為執行的時間比較少,而線程本身執行的時間占的比重比較大; 對於下載和上傳,因為本身就是比較消耗時間的操作,因此每個串連單獨使用了線程建立和銷毀,因為時間比較久,線程的時間可以忽略了"""import threadingimport queueimport timeimport paramikoimport os#找到相對路徑parent_path = os.path.abspath(os.pardir)db_path=os.path.join(parent_path,‘db‘)#一個管理類,基本思路是把任務和相關的參數填充到隊列(任務池)中,然後建立一個進程池,裡面的進程迴圈地讀取任務池裡面的內容,任何執行其中的內容,直到所有任務全部實現。class workmanager(object):    #建構函式    def __init__(self,cmd,username,password,work_num=1000,thread_num=2,):        """        :param cmd:遠程命令        :param username: 使用者名稱        :param password: 密碼        :param work_num: 任務池(隊列大小)        :param thread_num: 線程池大小        """        self.cmd=cmd        self.work_num=work_num        self.thread_num=thread_num        self.queue=queue.Queue()        self.threads=[]        self.init_task(work_num,cmd,username,password)        self.init_threadpool(thread_num)    #初始化任務池    def init_task(self,num,inp,username,password):        for i in range(num):            self.add_job(do_job,i,inp,username,password)    #新增工作到任務池    def add_job(self,job,*args):        #填充任務到任務池,每一個任務是一個元祖(任務,參數列表)        self.queue.put((job,list(args)))    #初始化線程池    def init_threadpool(self,num):        for i in range(num):            self.threads.append(work(self.queue))    #等待掛起主線程    def wait_allcomplete(self):        for item in self.threads:            if item.isAlive():                item.join()#線程類,每個線程迴圈地去任務池取任務class work(threading.Thread):    def __init__(self,que):        super(work, self).__init__()        self.queue=que        self.start()    def run(self):        while True:            try:                #當任務池為空白的時候,強制報錯,退出                do,args=self.queue.get(block=False)                # print(do,args)                do(args[0],args[1],args[2],args[3])                #確保隊列裡面的任務都完成了                self.queue.task_done()            except:                break#初始化的一個主機群組,測試用的hosts=[‘anoble-ise‘,‘bberry-ise‘,‘blackbr-ise‘,‘jlau-ise‘,‘kwood-ise‘,‘marwa-ise‘,‘smaroo-ise‘,‘psekarwin-ise‘,‘spare2-ise‘]#遠端連線SSH並且執行命令def do_job(args,inp,username,password):    """    :param args: hosts列表的索引    :param inp: 遠程命令    :param username: 使用者名稱    :param password: 密碼    :return:    """    # time.sleep(0.1)    ssh = paramiko.SSHClient()    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())    ssh.connect(hosts[args], 22, username, password)    # 執行命令測試    stdin, stdout, stderr = ssh.exec_command(inp)    for line in stdout.readlines():        print(line.strip())    print(("\x1b[5;19;32m  %s \x1b[0m" % hosts[args]).center(40,‘*‘))    print("\n")#下載測試def download(args,user,pwd,remote,local):    """    :param args: hosts列表的索引    :param inp: 遠程命令    :param username: 使用者名稱    :param password: 密碼    :return:    """    try:        # print(hosts[args])        t = paramiko.Transport((hosts[args],22))        t.connect(username=user, password=pwd)        sftp = paramiko.SFTPClient.from_transport(t)        # remotepath=‘/tmp/test2‘        if not os.path.isdir(local):            os.makedirs(local)        remotepath=remote        localpath=os.path.join(local,hosts[args])        sftp.get(remotepath, localpath)        print("下載檔案從%s成功" % hosts[args])    except Exception as ex:        print("下載檔案從%s失敗"%hosts[args])# 上傳測試def upload(args,user,pwd,remote,local):    try:        # print(hosts[args])        t = paramiko.Transport((hosts[args], 22))        t.connect(username=user, password=pwd)        sftp = paramiko.SFTPClient.from_transport(t)        # remotepath=‘/tmp/test2‘        remotepath=remote        localpath=local        # localpath=‘c:/temp/aaa.txt‘        sftp.put(localpath, remotepath)        print(‘上傳檔案到%s成功‘ % hosts[args])        t.close()    except Exception as ex:        print(‘上傳檔案到%s失敗‘%hosts[args])#選擇主機群組def hostinfo():    global hosts    print("可供選擇的主機群組包括:")    from os import listdir    from os.path import isfile, join    # mypath=os.getcwd()    onlyfiles = [f for f in listdir(db_path) if isfile(join(db_path, f))]    print(onlyfiles)    for file in onlyfiles:        file_path=os.path.join(db_path,file)        with open(file_path,‘r‘) as fp:           print(("\x1b[5;19;32m %s 主機列表 \x1b[0m" %file).center(40, ‘*‘))           for line in fp:               print(line.strip())    name=input("請選擇你要操作的主機群組名稱(hostgroup1,hostgroup2,hostgroup3..)")    if name in onlyfiles:        hosts=[]        file_path=os.path.join(db_path,name)        with open(file_path,‘r‘) as fp:            for line in fp:                hosts.append(line.strip())    else:        print("該主機群組不存在")username=""password=""#入口檔案def display():    global hosts,username,password    msg="""    歡迎使用Fabric類比程式,您可以執行以下操作    1.顯示主機群組    2.批量執行遠程命令    3.批量上傳    4.批量下載    5.輸入管理員帳號    6.退出    """    msg2 = """    1.選擇主機群組    2.列出當前主機列表    3.返回上一級目錄     """    while True:        print(msg)        inpt=input("請輸入選項")        #輸出主機群組的相關資訊        if inpt==‘1‘:            while True:                print(msg2)                opt=input("請輸入選項")                if opt==‘1‘:                    hostinfo()                elif opt==‘2‘:                    for item in hosts:                        print(item)                elif opt==‘3‘:break                else:print("非法輸入")        #遠程大量操作        elif inpt==‘2‘:            # username=input("使用者名稱")            # password=input("密碼")            if not username:                print("請先配置登入帳號資訊")            else:                while True:                    inp = input("輸入指令(q返回上級目錄)\n>>>")                    if inp ==‘q‘:break                    if not inp:                        print("不能輸入空命令")                    else:                        start = time.time()                        #指定命令,使用者名稱,密碼,任務池(隊列)的大小,和線程的個數)                        work_manager = workmanager(inp,username,password, len(hosts), 20)                        work_manager.wait_allcomplete()                        end = time.time()                        print("Cost time is %s" % (end - start))        #建立批量上傳的多線程        elif inpt==‘3‘:            if not username:                print("請先配置登入帳號資訊")            else:                remote_path=input("遠程路徑")                local_path=input("當前路徑")                threads = []                for item in range(len(hosts)):                    t = threading.Thread(target=upload, args=(item,username,password,remote_path,local_path))                    t.start()                    threads.append(t)                for t in threads:                    t.join()        #建立批量下載的多線程        elif inpt==‘4‘:            if not username:                print("請先配置登入帳號資訊")            else:                remote_path = input("遠程檔案路徑")                local_path = input("當前檔案夾路徑")                threads=[]                for item in range(len(hosts)):                    t = threading.Thread(target=download, args=(item,username,password,remote_path,local_path))                    t.start()                    threads.append(t)                for t in threads:                    t.join()        elif inpt==‘5‘:            username = input("使用者名稱")            password = input("密碼")        elif inpt==‘6‘:            exit("退出程式")        else:            print("無效輸入,請重試")if __name__ == ‘__main__‘:    display()

跑起來介面大概是這樣的

PowerShell 指令碼

然後純屬無聊,我用Powershell也簡單的實現了一次。Powershell主要是用第三方模組 posh-ssh進行串連。這個模組本身沒有提供多線程的功能,這裡偷懶,豆子也沒用runspace(多線程),也沒寫異常處理,就想看看是否工作。因此他串連session的時候不是並行作業,而是挨個執行,花了可能10分鐘才和幾百個蘋果用戶端建立了ssh session,比起上面的Python指令碼慢很多。

#先找到所有的蘋果系統,排除ping不通的$sydmac=Get-ADComputer -Filter {operatingsystem -like ‘*MAC*‘}  -Properties ipv4address | Where-Object {$_.ipv4address -notlike ‘‘}$sydmac| select -expand dnshostname |Invoke-Parallel -ScriptBlock {Test-Connection -ComputerName "$_" -Count 1 -ErrorAction SilentlyContinue -ErrorVariable err | select Ipv4address, @{n=‘DNS‘;e={[System.Net.Dns]::gethostentry($_.ipv4address).hostname}}} -Throttle 20 | select -ExpandProperty dns| out-file c:\temp\mac.txt$list=gc C:\temp\mac.txtImport-Module posh-ssh#密碼帳號    $username = "administrator"$secureStringPwd = ConvertTo-SecureString -AsPlainText "111222333" -Force$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd#這裡迴圈寫的很low 很慢,和每個用戶端分別建立session,稍後有空改成隊列+runspace的多線程試試foreach($line in $list){New-SSHSession -ComputerName $line -Credential ( get-credential $creds ) -AcceptKey}$sessions=Get-SSHSessionfor($i=0;$i -lt $sessions.Length;$i++){Invoke-SSHCommand -Command ‘ifconfig | grep ether‘ -Sessionid $i -ErrorAction SilentlyContinue}``

上面的指令碼都能工作,不過代碼品質比較挫,之後有時間再慢慢最佳化。

Windows 下指令碼遠端管理數百台蘋果系統

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.