2007年5月24日星期四

[Tips]用perl来处理mbsa的结果

Author: 云舒@ph4nt0m
Date: 2007-05-14
http://www.ph4nt0m.org

相信很多人和我遇到一样的问题,那就是windows自动升级时,svchost进程占用了100%的CPU导致什么都做不了了,不升级吧,那显然是不行的。但是自己手动下载补丁安装,就不会消耗cpu资源了,但是这样操作起来太麻烦,我就写了这样一个perl脚本老进行自动执行。首先使用mbsa扫描系统,找到没有安装的补丁,然后使用perl对扫描报告进行分析,自动下载补丁保存到本地来。

微软比较不厚道的是,把扫描报告藏起来了,我的winxp系统,mbsa2.1版本,扫描结果在这里:C:\Documents and Settings\Administrator\SecurityScans,文件其实都是普通的xml文件,只是扩展名被改为mbsa了,文件里面的 DownloadURL就是我们需要的。

perl脚本如下,主要就是解析XML文档,再使用lwp来下载,很简单,我就不注释了:
代码:

# 2007年5月14日下午,闷热无聊的周一,by 云舒

use warnings;
use strict;
use LWP::Simple;
use XML::Simple;
use XML::Parser;

# 这里都定义死了,因为是我自己用啊,呵呵
my $scan_reports = "hotfix.xml";
my $directory = "F:\hotfix\";

my $flag = "DownloadURL";

my $tag;
my @urls;

# 去掉字符串前后的空白字符
sub Trim
{
        
my $string = shift;

        
$string =~ s/^\s+//;
        
$string =~ s/\s+$//;
        
        
return $string;
}

print "Code by yunshu,used to download hotfix from microsoft.\n\n";

my $parser = new XML::Parser(ErrorContext => 2);

$parser->setHandlers( Start => \&startElement, End => \&endElement, Char => \&characterData, Default => \&default );

$parser->parsefile( $scan_reports );

foreach my $url ( @urls )
{
    
my @fields = split'/', $url );
    
my $count = @fields;
    
my $file_name = $fields$count - 1 ];
    
    
my $full_path = $directory.$file_name;
    
if( not -$full_path )
    {
        
print "Try to download $url\n";
        getstore( 
$url, $full_path );
    }
    
else
    {
        
print "$full_path is exists,test next.\n";
    }
}

sub startElement
{
    
my$parseinst, $element, %attrs ) = @_;

    
if ($element eq "DownloadURL")
    {
        
$tag = "DownloadURL";
    }
    
else
    {
        
$tag = "defalut";
    }
}

sub endElement
{
    
my$parseinst, $element ) = @_;
}

sub characterData
{
    
my$parseinst, $data ) = @_;

    
if$tag eq $flag )
    {
        
chomp$data );
        
        
my $url = Trim($data);
        
        
if$url ne "" )
        {
            
push@urls, $url );
        }
    }
}

sub default
{
    
my ( $parseinst, $data ) = @_;
}


没有评论: