Windows服务器Pyton辅助运维--02.远程重启IIS服务器

Windows服务器Pyton辅助运维

02.远程重启IIS服务器

开发环境:

Web服务器:

Windows Server 2008 R2 SP1

IIS 7.5

运维服务器:

Python 2.7.8

    组件:pywin32(219)   wmi(1.4.9)

工作内容说明:

每次排除故障的时候开发人员都会要求重启Web服务器上的IIS,有很多台IIS服务器需要重启,当然Google知道bat可以搞定这件事,但是本文用python来搞定。

实现过程:

先准备以下几个问题

使用Windows自带命令行工具如何远程重启IIS?

  1. WMI服务

          需要远程服务器安装并启动WMI服务

          如何写命令?

     2. Psexesc工具

          首先去微软网站上下载这个工具

          然后执行下面这个命令

          psexec \\192.168.1.X -u administrator -p ***** iisreset

          然后会输出如下

          

Python代码的设计思路?

  1. 去搜个WMI的Python库(本文所采用
  2. 去搜个Psexec的Python库(搜到了不会用Corelabs的Impacket
  3. 直接import os 执行psexec远程命令(有问题无法看到返回信息)

 

整一个配置文件记录基本信息AppConfig.ini

 1 [DepolyFiles]
 2 
 3 LocalDir=C:\Deploy
 4 
 5 RemoteDir=E:\Deploy
 6 
 7 Servers=192.168.1.2-23|192.168.1.37
 8 
 9 UserId=administrator
10 
11 Password=*******
12 
13 UseIISRestart= false

 

Servers配置节中“|”是分隔符,可以填写多个IP,“-”符号表示连续IP。

 

然后去搜一个WMI的Python实现代码如下RemoteCommands.py

  1 __author__="*****"
  2 __date__ ="*****"
  3 
  4 import os
  5 import wmi
  6 import shutil
  7 import win32wnet
  8 import ConfigParser
  9 
 10 REMOTE_PATH = 'c:\\'
 11 
 12 def main():
 13     pIniFileName = "AppConfig.ini";
 14 
 15     config = ConfigParser.ConfigParser()
 16     config.readfp(open(pIniFileName,"rb"))
 17 
 18     LocalDir = config.get("DepolyFiles","LocalDir").strip()
 19     RemoteDir = config.get("DepolyFiles","RemoteDir").strip()
 20     Servers = config.get("DepolyFiles","Servers").strip()
 21     UserId = config.get("DepolyFiles","UserId").strip()
 22     Password = config.get("DepolyFiles","Password").strip()
 23     UseIISRestart = config.get("DepolyFiles","UseIISRestart").strip()
 24 
 25     print "LocalDir : "+LocalDir
 26     print "RemoteDir : "+RemoteDir
 27     print "Servers : "+Servers
 28     print "UserId : "+UserId
 29     print "Password : "+Password
 30     print "UseIISRestart : "+UseIISRestart
 31 
 32     pServerSplit = Servers.split('|');
 33     pServerList = list();
 34     for itemServer in pServerSplit:
 35         sServerString = itemServer.strip();
 36         if(sServerString.find('-')>0):
 37             tempList = sServerString.split('-');
 38             iStartValue = int(tempList[0].split('.')[3]);
 39             iEndValue = int(tempList[1]);
 40             sFrontString = tempList[0].split('.')[0]+"."+tempList[0].split('.')[1]+"."+tempList[0].split('.')[2]+".";
 41             while iStartValue<=iEndValue:
 42                 pServerList.append(sFrontString+str(iStartValue));
 43                 iStartValue=iStartValue+1;
 44         else:
 45             pServerList.append(sServerString);
 46 
 47     for webServer in pServerList:
 48         ip = webServer
 49         username = UserId
 50         password = Password
 51         print '';
 52         
 53         server = WindowsMachine(ip, username, password)
 54         resultlist = server.run_remote('iisreset',async=True, output=True);
 55         for linestring in resultlist:
 56             print linestring
 57 
 58 def create_file(filename, file_text):
 59     f = open(filename, "w")
 60     f.write(file_text)
 61     f.close() 
 62 
 63 class WindowsMachine:
 64     def __init__(self, ip, username, password, remote_path=REMOTE_PATH):
 65         self.ip = ip
 66         self.username = username
 67         self.password = password
 68         self.remote_path = remote_path
 69         try:
 70             print "Establishing connection to %s" %self.ip
 71             self.connection = wmi.WMI(self.ip, user=self.username, password=self.password)
 72             print "Connection established"
 73         except wmi.x_wmi:
 74             print "Could not connect to machine"
 75             raise
 76 
 77     def run_remote(self, cmd, async=False, minimized=True, output=False):
 78         """
 79         this function runs cmd on remote machine, using wmi. the function create a .bat file,
 80         copies it to the remote machine, and runs the .bat file
 81         inputs: cmd - command to run
 82                 async - False, waits for command to finish, True, return immidiatly
 83                 mimimized - window state
 84                 output - True, returns the command's output
 85         output: return value of the command
 86                 output of the command if true
 87         """
 88         output_data = None
 89         pwd = os.getcwd()
 90         bat_local_path = os.path.join(pwd, 'output_{0}.bat'.format(self.ip))
 91         bat_remote_path = os.path.join(self.remote_path, 'output_{0}.bat'.format(self.ip))
 92         output_remote_path = os.path.join(self.remote_path, 'output_{0}.out'.format(self.ip))
 93         output_local_path = os.path.join(pwd, 'output_{0}.out'.format(self.ip))
 94         text = cmd + " > " + output_remote_path
 95         create_file(bat_local_path, text)
 96         self.net_copy(bat_local_path, self.remote_path)
 97         batcmd = bat_remote_path
 98 
 99         SW_SHOWMINIMIZED = 0
100         if not minimized:
101             SW_SHOWMINIMIZED = 1
102         print "Executing %s" %cmd
103         startup = self.connection.Win32_ProcessStartup.new (ShowWindow=SW_SHOWMINIMIZED)
104         process_id, return_value = self.connection.Win32_Process.Create (CommandLine=batcmd, ProcessStartupInformation=startup)
105         if async:
106             watcher = self.connection.watch_for (
107                                   notification_type="Deletion",
108                                   wmi_class="Win32_Process",
109                                   delay_secs=1,
110                                   )
111             watcher ()
112 
113         if output:
114             print 'copying back ' + output_remote_path
115             self.net_copy_back(output_remote_path, output_local_path)
116             output_data = open(output_local_path, 'r')
117             output_data = "".join(output_data.readlines())
118             self.net_delete(output_remote_path)
119         self.net_delete(bat_remote_path)
120         return return_value, output_data
121 
122     def net_copy(self, source, dest_dir, move=False):
123         """ Copies files or directories to a remote computer. """
124         print "Start copying files to " + self.ip
125         if self.username == '':
126             if not os.path.exists(dest_dir):
127                 os.makedirs(dest_dir)
128             else:
129                 # Create a directory anyway if file exists so as to raise an error.
130                  if not os.path.isdir(dest_dir):
131                      os.makedirs(dest_dir)
132             shutil.copy(source, dest_dir)
133 
134         else:
135             self._wnet_connect()
136 
137             dest_dir = self._covert_unc(dest_dir)
138 
139             # Pad a backslash to the destination directory if not provided.
140             if not dest_dir[len(dest_dir) - 1] == '\\':
141                 dest_dir = ''.join([dest_dir, '\\'])
142 
143             # Create the destination dir if its not there.
144             if not os.path.exists(dest_dir):
145                 os.makedirs(dest_dir)
146             else:
147                 # Create a directory anyway if file exists so as to raise an error.
148                  if not os.path.isdir(dest_dir):
149                      os.makedirs(dest_dir)
150 
151             if move:
152                 shutil.move(source, dest_dir)
153             else:
154                 shutil.copy(source, dest_dir)
155 
156     def net_copy_back(self, source_file, dest_file):
157         """ Copies files or directories to a remote computer. """
158         print "Start copying files " + source_file +  " back from " + self.ip
159         if self.username == '':
160             shutil.copy(source_file, dest_file)
161         else:
162             self._wnet_connect()
163             source_unc =  self._covert_unc(source_file)
164             shutil.copyfile(source_unc, dest_file)
165 
166     def _wnet_connect(self):
167         unc = ''.join(['\\\\', self.ip])
168         try:
169             win32wnet.WNetAddConnection2(0, None, unc, None, self.username, self.password)
170         except Exception, err:
171             if isinstance(err, win32wnet.error):
172                 # Disconnect previous connections if detected, and reconnect.
173                 if err[0] == 1219:
174                     win32wnet.WNetCancelConnection2(unc, 0, 0)
175                     return self._wnet_connect(self)
176             raise err
177 
178     def _covert_unc(self, path):
179         """ Convert a file path on a host to a UNC path."""
180         return ''.join(['\\\\', self.ip, '\\', path.replace(':', '$')])
181 
182     def copy_folder(self, local_source_folder, remote_dest_folder):
183         files_to_copy = os.listdir(local_source_folder)
184         for file in files_to_copy:
185             file_path = os.path.join(local_source_folder, file)
186             print "Copying " + file
187             if(os.path.isdir(file_path)):
188                 self.copy_folder(file_path,remote_dest_folder+"\\"+file);
189             else:
190                 try:
191                     self.net_copy(file_path, remote_dest_folder)
192                 except WindowsError:
193                     print 'could not connect to ', self.ip
194                 except IOError:
195                     print 'One of the files is being used on ', self.ip, ', skipping the copy procedure'
196 
197     def net_delete(self, path):
198         """ Deletes files or directories on a remote computer. """
199         try:
200             if self.username == '':
201                 os.remove(path)
202 
203             else:
204                 self._wnet_connect()
205 
206                 path = self._covert_unc(path)
207                 if os.path.exists(path):
208                     # Delete directory tree if object is a directory.
209                     if os.path.isfile(path):
210                         os.remove(path)
211                     else:
212                         shutil.rmtree(path)
213                 else:
214                     # Remove anyway if non-existent so as to raise an error.
215                     os.remove(path)
216         except:
217             print 'could not delete ', path
218 
219 if __name__ == "__main__":
220     main()
View Code

 

备注:请确保在一个运维机器和Web服务器在同一个局域网中.请确保远程服务器WMI服务开启.

posted on 2014-08-13 18:47  赵云会编程  阅读(680)  评论(0编辑  收藏  举报