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

然后会输出如下

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

Python代码的设计思路?

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

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

 [DepolyFiles]

 LocalDir=C:\Deploy

 RemoteDir=E:\Deploy

 Servers=192.168.1.2-23|192.168.1.37

 UserId=administrator

 Password=*******

 UseIISRestart= false

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

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

 __author__="*****"
__date__ ="*****" import os
import wmi
import shutil
import win32wnet
import ConfigParser REMOTE_PATH = 'c:\\' def main():
pIniFileName = "AppConfig.ini"; config = ConfigParser.ConfigParser()
config.readfp(open(pIniFileName,"rb")) LocalDir = config.get("DepolyFiles","LocalDir").strip()
RemoteDir = config.get("DepolyFiles","RemoteDir").strip()
Servers = config.get("DepolyFiles","Servers").strip()
UserId = config.get("DepolyFiles","UserId").strip()
Password = config.get("DepolyFiles","Password").strip()
UseIISRestart = config.get("DepolyFiles","UseIISRestart").strip() print "LocalDir : "+LocalDir
print "RemoteDir : "+RemoteDir
print "Servers : "+Servers
print "UserId : "+UserId
print "Password : "+Password
print "UseIISRestart : "+UseIISRestart pServerSplit = Servers.split('|');
pServerList = list();
for itemServer in pServerSplit:
sServerString = itemServer.strip();
if(sServerString.find('-')>0):
tempList = sServerString.split('-');
iStartValue = int(tempList[0].split('.')[3]);
iEndValue = int(tempList[1]);
sFrontString = tempList[0].split('.')[0]+"."+tempList[0].split('.')[1]+"."+tempList[0].split('.')[2]+".";
while iStartValue<=iEndValue:
pServerList.append(sFrontString+str(iStartValue));
iStartValue=iStartValue+1;
else:
pServerList.append(sServerString); for webServer in pServerList:
ip = webServer
username = UserId
password = Password
print ''; server = WindowsMachine(ip, username, password)
resultlist = server.run_remote('iisreset',async=True, output=True);
for linestring in resultlist:
print linestring def create_file(filename, file_text):
f = open(filename, "w")
f.write(file_text)
f.close() class WindowsMachine:
def __init__(self, ip, username, password, remote_path=REMOTE_PATH):
self.ip = ip
self.username = username
self.password = password
self.remote_path = remote_path
try:
print "Establishing connection to %s" %self.ip
self.connection = wmi.WMI(self.ip, user=self.username, password=self.password)
print "Connection established"
except wmi.x_wmi:
print "Could not connect to machine"
raise def run_remote(self, cmd, async=False, minimized=True, output=False):
"""
this function runs cmd on remote machine, using wmi. the function create a .bat file,
copies it to the remote machine, and runs the .bat file
inputs: cmd - command to run
async - False, waits for command to finish, True, return immidiatly
mimimized - window state
output - True, returns the command's output
output: return value of the command
output of the command if true
"""
output_data = None
pwd = os.getcwd()
bat_local_path = os.path.join(pwd, 'output_{0}.bat'.format(self.ip))
bat_remote_path = os.path.join(self.remote_path, 'output_{0}.bat'.format(self.ip))
output_remote_path = os.path.join(self.remote_path, 'output_{0}.out'.format(self.ip))
output_local_path = os.path.join(pwd, 'output_{0}.out'.format(self.ip))
text = cmd + " > " + output_remote_path
create_file(bat_local_path, text)
self.net_copy(bat_local_path, self.remote_path)
batcmd = bat_remote_path SW_SHOWMINIMIZED = 0
if not minimized:
SW_SHOWMINIMIZED = 1
print "Executing %s" %cmd
startup = self.connection.Win32_ProcessStartup.new (ShowWindow=SW_SHOWMINIMIZED)
process_id, return_value = self.connection.Win32_Process.Create (CommandLine=batcmd, ProcessStartupInformation=startup)
if async:
watcher = self.connection.watch_for (
notification_type="Deletion",
wmi_class="Win32_Process",
delay_secs=1,
)
watcher () if output:
print 'copying back ' + output_remote_path
self.net_copy_back(output_remote_path, output_local_path)
output_data = open(output_local_path, 'r')
output_data = "".join(output_data.readlines())
self.net_delete(output_remote_path)
self.net_delete(bat_remote_path)
return return_value, output_data def net_copy(self, source, dest_dir, move=False):
""" Copies files or directories to a remote computer. """
print "Start copying files to " + self.ip
if self.username == '':
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
else:
# Create a directory anyway if file exists so as to raise an error.
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir)
shutil.copy(source, dest_dir) else:
self._wnet_connect() dest_dir = self._covert_unc(dest_dir) # Pad a backslash to the destination directory if not provided.
if not dest_dir[len(dest_dir) - 1] == '\\':
dest_dir = ''.join([dest_dir, '\\']) # Create the destination dir if its not there.
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
else:
# Create a directory anyway if file exists so as to raise an error.
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir) if move:
shutil.move(source, dest_dir)
else:
shutil.copy(source, dest_dir) def net_copy_back(self, source_file, dest_file):
""" Copies files or directories to a remote computer. """
print "Start copying files " + source_file + " back from " + self.ip
if self.username == '':
shutil.copy(source_file, dest_file)
else:
self._wnet_connect()
source_unc = self._covert_unc(source_file)
shutil.copyfile(source_unc, dest_file) def _wnet_connect(self):
unc = ''.join(['\\\\', self.ip])
try:
win32wnet.WNetAddConnection2(0, None, unc, None, self.username, self.password)
except Exception, err:
if isinstance(err, win32wnet.error):
# Disconnect previous connections if detected, and reconnect.
if err[0] == 1219:
win32wnet.WNetCancelConnection2(unc, 0, 0)
return self._wnet_connect(self)
raise err def _covert_unc(self, path):
""" Convert a file path on a host to a UNC path."""
return ''.join(['\\\\', self.ip, '\\', path.replace(':', '$')]) def copy_folder(self, local_source_folder, remote_dest_folder):
files_to_copy = os.listdir(local_source_folder)
for file in files_to_copy:
file_path = os.path.join(local_source_folder, file)
print "Copying " + file
if(os.path.isdir(file_path)):
self.copy_folder(file_path,remote_dest_folder+"\\"+file);
else:
try:
self.net_copy(file_path, remote_dest_folder)
except WindowsError:
print 'could not connect to ', self.ip
except IOError:
print 'One of the files is being used on ', self.ip, ', skipping the copy procedure' def net_delete(self, path):
""" Deletes files or directories on a remote computer. """
try:
if self.username == '':
os.remove(path) else:
self._wnet_connect() path = self._covert_unc(path)
if os.path.exists(path):
# Delete directory tree if object is a directory.
if os.path.isfile(path):
os.remove(path)
else:
shutil.rmtree(path)
else:
# Remove anyway if non-existent so as to raise an error.
os.remove(path)
except:
print 'could not delete ', path if __name__ == "__main__":
main()

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

上一篇:Android(java)学习笔记77:网络编程的概述


下一篇:转 Caffe学习系列(5):其它常用层及参数