捐血一袋救人一命

江蘇拙政園

江蘇 拙政園

全家福

日本 和歌山城

賞楓之旅

千燈 夕照

水鄉千燈

蘆洲 微風運河

破曉時分

顯示具有 Windows Script and Batch Files 標籤的文章。 顯示所有文章
顯示具有 Windows Script and Batch Files 標籤的文章。 顯示所有文章

2012年10月30日 星期二

如何在命令行引數下產生一個區間的亂數

Windows Command Shell 底下內建一個亂數變數 %random%

它產生的數值介於 0~32767 之間。

要將它局限在一定區間,以便程式應用!

2012年2月13日 星期一

搜尋 Event Log 中的文字並匯出成 .csv 檔案

Windows的事件檢視器可以把大小事都記錄下來,但是卻沒有提供良好的工具去搜尋,所以只好寫程式來輔助。

起始肇因公司要求對某些目錄檔案進行稽核記錄,但是這些檔案使用又非常頻繁,所以當發現需要檢視事件記錄時,常有上萬筆記錄;而事件檢視器並不提供針對檔名或是訊息當中的字串做為篩選條件,只能用事件代碼;要針對某檔案進行稽核時,就成了不可能的任務!

在以下程式中,有幾個參數要設定
strComputer 是指要被搜尋事件檢視器記錄的電腦名稱或 IP Address
strSearchString 是要被搜尋的字串
dtmLogDate 是匯出的檔名,我個人習慣在匯出檔案名稱加上日期,以方便處理;看您個人的習慣囉

strComputer = "DFS1"
strSearchString = “SHARE”
dtmLogDate = ‘20120213”

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Security)}!\\" & strComputer & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery ("Select * FROM Win32_NTLogEvent WHERE Logfile = 'Security'")

Const ForWriting = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile("FileLog" & dtmLogDate & ".csv", ForWriting, True)
    objLogFile.Write "Record Number#"
    objLogFile.Write "Date Time#"
    objLogFile.Write "Message"
    objLogFile.WriteLine
For Each objEvent in colLoggedEvents
    if InStr(objEvent.Message,strSearchString) > 0 then
        objLogFile.Write objEvent.RecordNumber & "#"
        objLogFile.Write objEvent.TimeGenerated & "#"
        objEvent.Message = replace(objEvent.Message,vbCRLF,"")
        objLogFile.Write objEvent.Message
        objLogFile.WriteLine
    end if
Next
objLogFile.Close
msgbox("Finish !")

2012年1月6日 星期五

管理網域帳號在本機的權限群組

功能:遠端維護→將使用者的帳號,加入/移出某電腦的本機的群組

image

2011年7月21日 星期四

自動化阻擋 SMTP/POP3 Authtication Attack

前一陣子公司不斷遭遇到 Cracker 攻擊 Exchange 2003 的 SMTP/POP3 服務,

企圖以暴力方式破解信箱帳號密碼。

由於本公司採用中華電信的資安艦隊服務,所以將 SMTP/POP3 Log Dump 出來之後,寄交中華電信處理。

中華電信將 IPS 的觸發值調低之後,安穩了兩天;兩天之後,卻發現 Cracker 改變攻擊的頻率,變成每兩秒 Try 一次帳號密碼。

當我將此發現告知中華電信資安艦隊服務人員之後,中華電信人員表示,由於駭客攻擊的頻率已經很低,無法攔阻這樣的攻擊,建議加強密碼政策管理來補強。

身為一個網路管理者,看到這樣的 Log 當然很不爽,駭客天天來家門口踩盤子,所以決定自己動手寫程式,強化 Exchange 防護措施

2011年6月24日 星期五

Check SMTP Authentication

相信很多公司的郵件伺服器都會開放 SMTP 25 Port ,供差旅同仁方便寄信。

但這也給予Cracker / SPAMER SMTP Auth Relay Attack 的機會。

這會造成公司的郵件主機被列入黑名單之中…(網路上還是有不少公司堅持使用這種落伍的黑名單技術來阻擋廣告信)

到時同仁就會一直反應會被退信…

因為從外部透過公司郵件主機 Relay ,需要進行 SMTP 驗證

所以我寫了一支程式去監控事件檢視器,搭配 Exchange 的 SMTP 驗證記錄;如果有 SMTP 驗證成功的訊息,就會在我的電腦 Pop Up 一個提醒視窗。

首先把 Exchange 的 SMTP 驗證事件開啟

2011-06-24_113509

2011-06-24_113629

接著在本機執行以下程式(請存成 .vbs 檔案,然後執行它)

strComputer = "MAIL"

Set objWMIService = GetObject("winmgmts:{(Security)}\\" & strComputer & "\root\cimv2")

Set colMonitoredEvents = objWMIService.ExecNotificationQuery ("Select * from __InstanceCreationEvent Where " & "TargetInstance ISA 'Win32_NTLogEvent' " & "and TargetInstance.EventCode = '1708'")
Do
    Set objLatestEvent = colMonitoredEvents.NextEvent
    Wscript.Echo "User:" & objLatestEvent.TargetInstance.User & chr(13) & "DateTime:" & objLatestEvent.TargetInstance.TimeWritten & chr(13) & "Log:" & objLatestEvent.TargetInstance.Message

Loop

其中 1708 是 SMTP 驗證成功的事件代碼

當程式監控到 Event 時,就會跳出如下的視窗。

image

 

有人說:DNS MX 記錄指向 AntiSPAM 設備就不會受到 SMTP Auth Attack ,這是一個嚴重的錯誤觀念!

駭客要攻擊都會直接掃瞄 25 Port ,有誰開 25 Port ,就會被 Try…

2010年4月21日 星期三

找出與今日日期相同的檔案

@echo off
setlocal EnableDelayedExpansion
set Today="%DATE:~0,10%"
for /F %%I in ( 'dir *.dat /b' ) do (
set DT="%%~tI"
set FDT=!DT:~1,10!
if "!FDT!"==%Today% (
echo "%%~I"
) else (
echo wrong
)
)
endlocal

在 for 迴圈中,如果變數是檔名,可以利用以下格式,來讀取檔案相關資訊
(以 %I 為 for 迴圈變數,如果迴圈變數名不是 I,請將以下格式的 I 改掉)
%~I 檔名前後會自動加上雙引號
%~fI 會顯示該檔案的完整路徑+檔名
%~dI 顯示該檔案所在磁碟機代號
%~pI 顯示該檔案的完整路徑 (只有路徑,不含檔名)
%~nI 只顯示檔案名稱 (不含副檔名)
%~xI 只顯示檔案的副檔名 (不含主檔名)
%~sI 以短檔名格式顯示
%~aI 顯示檔案屬性 (AHRS)
%~tI 顯示檔案日期+時間
%~zI 顯示檔案大小
%~$PATH:I 搜尋PATH環境變數的每一個目錄,並顯示第一個符合檔名的完整路徑+檔名
以上的格式參數,可以組合使用。
例如:
%~nzI
以上,必須配合 for 迴圈的 /F 參數使用!
微軟官方網站的說明在此
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/for.mspx?mfr=true

將指定帳號加入某台電腦的本機管理者群組

image

strComputer = "ComputerName"

Set objAdmins = GetObject("WinNT://" & strComputer & "/Administrators")
Set objUser = GetObject("WinNT://DomainName/UserName")

objAdmins.Add(objUser.ADsPath)

要注意的是,使用者已經登入 Windows 後,才透過此程式加入管理者群組,並無法讓該使用者立即取得管理者權限。

使用者必須重新登入系統才會生效。

同樣的,如果使用者已具備管理者權限,即始使用此程式將使用者帳號移出本機管理者群組,管理者權限也不會立即失效,必須重新登入系統才能生效。

strComputer = "ComputerName"

Set objAdmins = GetObject("WinNT://" & strComputer & "/Administrators")
Set objUser = GetObject("WinNT://DomainName/UserName")

objAdmins.Add(objUser.ADsPath)

要注意的是,使用者已經登入 Windows 後,才透過此程式加入管理者群組,並無法讓該使用者立即取得管理者權限。

使用者必須重新登入系統才會生效。

同樣的,如果使用者已具備管理者權限,即始使用此程式將使用者帳號移出本機管理者群組,管理者權限也不會立即失效,必須重新登入系統才能生效。

<html>
<head>
<title>Add/Remove Domain Account into/from Local Administrator Group</title>

<HTA:APPLICATION
     ID="objHTAHelpomatic"
     APPLICATIONNAME="HTAManagementAccount"
     SCROLL="No"
     SINGLEINSTANCE="yes"
     BORDER="thick"
     BORDERSTYLE="raised"
     MAXIMIZEBUTTON="no"
     SHOWINTASKBAR="yes"
     WINDOWSTATE="normal"
>

</head>

<SCRIPT Language="VBScript">
' Setup Window Size
Sub Window_onLoad
    Const Width = 500
    Const Height = 250
    strComputer = "."
    self.ResizeTo width,height
    Self.moveTo (screen.AvailWidth-width)/2,(screen.AvailHeight-height)/2
End Sub

' Add Domain Account into Local Administrator Group
Sub AddAccount
    Set objAdmins = GetObject("WinNT://" & HostName.Value & "/Administrators")
    Set objGroup = GetObject("WinNT://Domain Name/" & Account.Value)
    objAdmins.Add(objGroup.ADsPath)
    msgbox("Finish !")
    set objGroup = Nothing
End Sub

' Displays a message box when the button is clicked
Sub RemoveAccount
    Set objAdmins = GetObject("WinNT://" & HostName.Value & "/Administrators")
    Set objGroup = GetObject("WinNT://Domain Name/" & Account.Value)
    objAdmins.Remove(objGroup.ADsPath)
    msgbox("Finish !")
    set objGroup = Nothing
End Sub
</SCRIPT>
<body>
您要在哪台電腦上管理 Administrators 群組?<br>
Host Name:<input type="text" name="HostName" size="30"><br>
Account:<input type="text" name="Account" size="32">(不含網域名稱)<br>
<input id=runbutton1  class="button" type="button" value="Add Account" name="run_button1"  onClick="AddAccount">
<input id=runbutton2  class="button" type="button" value="Remove Account" name="run_button2"  onClick="RemoveAccount"><br>
<br>
<ul>
<li>如果您輸入的電腦無法接受管理(例如:防火牆阻擋),將會發生錯誤訊息</li>
<li>如果您輸入的網域帳號不存在,也會發生錯誤訊息</li>
</ul>
</body>
</html>

PS.請記得將紅字的 Domain Name 更換成你的網域名稱

檢查網路某台電腦的本機管理者群組的非管理者帳號

在經歷許多環境發現,很多頗具規模的公司(以電腦數量來算),對於網域的管理,以及權限的管理都很鬆散。

隨隨便便一堆人都有本機管理者權限,當然公司會中毒、資料外洩也不足為奇。所以自己只要寫個簡單的小程式,就可以透過網路去檢查別台電腦的本機權限狀況。

MIS完全不用去中斷別人的工作,也不容易引起爭執。

當然在做這個動作之前,你最好先買個保險,由上級主管宣導實施,免得挨槍子。

strComputer = "ComputerName"

Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators")

For Each objUser In objGroup.Members
    If objUser.Name <> "Administrator" AND objUser.Name <> "Domain Admins" Then
        wscript.echo objUser.Name
    End If
Next

 

自動將 Exchange Archive SPAM 按照日期歸檔

使用 Exchange 2003 的 SPAM Archive 功能,會發現每天都有一堆信被封存,

才隔幾天,要開啟 Archive Folder時,卻系統卻會停止回應。

因為檔案太多,系統很忙碌的要一次讀取所有的檔案清單,

所以才有寫以下幾支程式的構想。

這支程式一執行,會將 E:\Exchsrvr\UCEArchive目錄下所有封存的 SPAM,按照日期格式 YYYYMMDD 歸檔存到 YYYYMMDD 目錄下,這樣子每個 Folder 的檔案數量不大,開啟資料夾速度就快多了。 ( Batch File )

@echo off
setlocal EnableDelayedExpansion
for /F %%a in ( 'dir E:\Exchsrvr\UCEArchive\*.EML /b' ) do (
set FileName=%%a
set DateDir=!FileName:~5,8!
if not exist E:\Exchsrvr\UCEArchive\!DateDir! mkdir E:\Exchsrvr\UCEArchive\!DateDir!
move E:\Exchsrvr\UCEArchive\!FileName! E:\Exchsrvr\UCEArchive\!DateDir!
)

這支程式只會抓今天的日期,將今天的 SPAM 歸檔 ( Batch File )

@echo off
for /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set date=%%a%%b%%c)
if not exist E:\Exchsrvr\UCEArchive\%date% mkdir E:\Exchsrvr\UCEArchive\%date%
move E:\Exchsrvr\UCEArchive\ARCH_%date%*.eml E:\Exchsrvr\UCEArchive\%date%

這支程式會抓昨天的日期,將昨天的 SPAM 歸檔 ( Windows Script Host )

' 取得昨天的日期
dtmYesterday = Date() - 1

' 將昨天的日期取出年份
strYear = left(dtmYesterday,4)

' 將昨天的日期取出月份
if mid(dtmYesterday,7,1) = "/" then
strMonth = "0" & mid(dtmYesterday,6,1)
else
strMonth = mid(dtmYesterday,6,2)
end if

' 將昨天的日期取出日期
if mid(dtmYesterday,len(dtmYesterday)-1,1) = "/" then
strDay = "0" & right(dtmYesterday,1)
else
strDay = right(dtmYesterday,2)
end if

strYesterday = strYear & strMonth & strDay

' 以昨天的日期來建立目錄
ParentFolder = "E:\Exchsrvr\UCEArchive"
set objShell = CreateObject("Shell.Application")
set objFolder = objShell.NameSpace(ParentFolder)

objFolder.NewFolder strYesterday

' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下
Set objFSO = CreateObject("Scripting.FileSystemObject")
FileNamePatten = "ARCH_" & strYesterday & "*.EML"
objFSO.MoveFile "E:\Exchsrvr\UCEArchive\" & FileNamePatten , "E:\Exchsrvr\UCEArchive\" & strYesterday

wscript.echo strYesterday & " Job is done !"

以下這支程式,會跳出視窗,讓您輸入日期,將指定日期的 SPAM 歸檔 ( Windows Script Host )

strDay = inputbox("請輸入日期 : ")

' 以昨天的日期來建立目錄
ParentFolder = "E:\Exchsrvr\UCEArchive"
set objShell = CreateObject("Shell.Application")
set objFolder = objShell.NameSpace(ParentFolder)

objFolder.NewFolder strDay

' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下
Set objFSO = CreateObject("Scripting.FileSystemObject")
FileNamePatten = "ARCH_" & strDay & "*.EML"
objFSO.MoveFile "E:\Exchsrvr\UCEArchive\" & FileNamePatten , "E:\Exchsrvr\UCEArchive\" & strDay

wscript.echo strDay & " Job is done !"

這是改用 Batch File 語法寫的程式,功能與上一支程式相同

set /p DateDir="請輸入日期:"
if not exist E:\Exchsrvr\UCEArchive\%DateDir% mkdir E:\Exchsrvr\UCEArchive\%DateDir%
move E:\Exchsrvr\UCEArchive\ARCH_%DateDir%*.eml E:\Exchsrvr\UCEArchive\%DateDir%

自動建立AD帳號程式

今天為了客戶寫了一支自動建帳號的程式

該程式將讀取 User 提供的帳號密碼清單來建立帳號


' Greate Accounts and Setting Password
' 讀取 List.txt 檔案中的帳號及密碼
' 將帳號建立在 strOU 這個組織單位中
' 並設定密碼
' List.txt 格式,每行一個帳號密碼,帳號與密碼以空格分開
' account password
' 如果使用者密碼有空白字元
' 請自己選用一個分隔符號,然後將第41行程式的空白字串改掉
' arrAccount = split(strAccountPW, " ")
' 設定單位組織
strOU = InputBox ( "請輸入組織單位名稱:" , "Greate Accounts under OU" , "SalesDept" )
' 設定 Domain
strDomain = InputBox ( "請輸入網域名稱:" , "Greate Accounts under OU" , "domain.com.tw" )
' 設定開啟檔案模式
Const ForReading = 1
' 宣告變數
strDC = ""
strLDAP = ""
strUserCN = ""
arrDC = split(strDomain,".")
for nLoop = 0 to UBound(arrDC)
strDC = strDC & "dc=" & arrDC(nLoop) & ","
next
strDC = left(strDC, LEN(strDC) - 1)
' wcscript.echo strDC
Set objOU = GetObject("LDAP://OU=" & strOU & "," & strDC)
' Read Account List File
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ("List.txt", ForReading)
Do Until objTextFile.AtEndOfStream
' 一行一行讀取 List.txt
strAccountPW = objTextFile.ReadLine
' 將 Account and Password 拆開,arrAccount(0)存帳號,arrAccount(1)存密碼
arrAccount = split(strAccountPW, " ")
' wscript.echo arrAccount(0) & ":" & arrAccount(1)
Set objUser = objOU.Create("User", "cn=" & arrAccount(0) )
objUser.Put "sAMAccountName", arrAccount(0)
objUser.Put "c", "TW"
objUser.Put "co", "台灣"
objUser.Put "countryCode", "886"
objUser.Put "mail", arrAccount(0) & "@" & strDomain
objUser.Put "name", arrAccount(0)
' Uncheck User need change password
' 將帳號物件寫入
  objUser.SetInfo
' 設定使用者預設密碼
Set objUser = GetObject ("LDAP://cn=" & arrAccount(0) & ",ou=" & strOU & "," & strDC)
objUser.SetPassword arrAccount(1)
' 使用變更密碼的方式來設定密碼
' objUser.ChangPassword "", arrAccount(1)
' 因為 Windows 2003 的預設密碼政策要求比較嚴格,可以使用下列預設密碼
' objUser.SetPassword "p@ssw0rd"
' 要求使用者下次登入要變更密碼
' objUser.Put "pwdLastSet", 0
' 取消帳號停用
objUser.AccountDisabled = FALSE
' 設定帳號過期日,Default為「永不過期」
' objUser.AccountExpirationDate = "1970/1/1"
objUser.SetInfo
Loop
' 關閉檔案
objTextFile.Close
wscript.echo "帳號建立完成"

使用 Ping 指令來檢查網路品質

最近為了客戶移機的事,又寫了一支WSH,它是用ping來檢測網路品質,將結果存到CSV File,然後寄到指定的信箱裡。

當我收到這個CSV File時,就可以把它匯入SQL Server,利用Excel來繪製網路品質的圖表。

On Error Resume Next
' Open File Mode (Read/Write)
Const ForAppending = 2
' 8 (hrs) * 60 (Minutes) * 60 (Seconds) = 28800
Const nTimes = 28800
' 1 Second = 1000
Const nSleep = 1000
' Branch Office Name

' 因為客戶有多個辦公室,所以加上一個Location欄位,以便日後分析
Const strLocation = "上海"
' Ping Server Public IP

' 這邊請輸入您自己要測試的端點 Public  IP
Const strPingServer = "123.123.123.123"

' 設定 SMTP Server
Const strSMTP = "xxx.xxx.xxx"

' 設定供 SMTP驗證的帳號
Const strUser = "UserName"

' 設定供 SMTP驗證的帳號密碼
Const strPasswd = "12345678"
' Initialize Variables 設定變數初始值
' Ping Status
nStatus = 0
strIP = ""
nResponseTime = 0
strAttachFile = ""
strMonth = Month(Date())
If Len(strMonth) = 1 Then
  strMonth = "0" & strMonth
End If
strDay = Day(Date())
If Len(strDay) = 1 Then
  strDay = "0" & strDay
End If
strYear = Year(Date())
strHour = Hour(Time())
If Len(strHour) = 1 Then
  strHour = "0" & strHour
End If
strMinute = Minute(Time())
If Len(strMinute) = 1 Then
  strMinute = "0" & strMinute
End If
strSecond = Second(Time())
If Len(strSecond) = 1 Then
  strSecond = "0" & strSecond
End If
strLogFile = "C:\" & strLocation & "_" & strYear & strMonth & strDay & "_" & strHour & strMinute & strSecond & ".txt"
' 檢查是否還存在 Log File,如果存在,就把它寄出去,然後刪掉(有可能之前 Ping 程式執行到一半就被中斷,例如關機或當機
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colFileList = objWMIService.ExecQuery ("ASSOCIATORS OF {Win32_Directory.Name='C:\'} Where " & "ResultClass = CIM_DataFile")
For Each objFile In colFileList
  If InStr(objFile.FileName, strLocation) Then
  strAttachFile = "C:\" & objFile.FileName & ".txt"
  ' 寄出 Log 檔案
  Set objEmail = CreateObject("CDO.Message")
  objEmail.From = "tombo@ms13.url.com.tw"
  objEmail.To = "tombo.katherine@gmail.com"
  objEmail.Subject = "Ping Status from" & strLocation & "@" & now()
  objEmail.Textbody = "Ping Status from " & strLocation
  objEmail.Addattachment strAttachFile
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTP
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = strUser
  objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = strPasswd
  objEmail.Configuration.Fields.Update
  objEmail.Send
  ' 刪除已寄出的 Log File
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  objFSO.DeleteFile(strAttachFile)
  End If
Next
' Check IP
strPublicIP = "xxx.xxx.xxx.xxx"
strURL="http://briian.com/files/act/myip-widget.php"
Set objHTTP = CreateObject("MSXML2.XMLHTTP")
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = True
objRegEx.Pattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
objHTTP.Open "GET", strURL, FALSE
objHTTP.Send
Set colMatches = objRegEx.Execute(objHTTP.ResponseText)
For Each strMatch in colMatches
strPublicIP = strMatch.Value
Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile ( strLogFile , ForAppending , True)
Set colServices = GetObject("winmgmts:").ExecQuery ("Select * from Win32_Service")
objTextFile.WriteLine( "Location" & "," & "Public IP" & "," & "Date" & "," & "Time" & "," & "Count" & "," & "Status Code" & "," & "Address" & "," & "ResponseTime")
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
for nLoop = 1 to nTimes
Set colItems = objWMIService.ExecQuery ("Select * from Win32_PingStatus " & "Where Address = '" & strPingServer & "'")
For Each objItem in colItems
  if objItem.StatusCode = 0 then
  nStatus = objItem.StatusCode
  strIP = objItem.Address
  nResponseTime = objItem.ResponseTime
  objTextFile.WriteLine( strLocation & "," & strPublicIP & "," & Date() & "," & Time() & "," & nLoop & "," & nStatus & "," & strIP & "," & nResponseTime )
  else ' Ping 不到的狀況
  objTextFile.WriteLine( strLocation & "," & strPublicIP & "," & Date() & "," & Time() & "," & nLoop & "," & nStatus & "," & strIP & "," & "-1" )
  end if
Next
Wscript.Sleep nSleep
Next 
objTextFile.Close
Set objEmail = CreateObject("CDO.Message")
objEmail.From = "tombo@ms13.url.com.tw"
objEmail.To = "tombo.katherine@gmail.com"
objEmail.Subject = "Ping Status from" & strLocation & "@" & now()
objEmail.Textbody = "Ping Status from " & strLocation
objEmail.Addattachment strLogFile
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTP
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = strUser
objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = strPasswd
objEmail.Configuration.Fields.Update
objEmail.Send
' 刪除已寄出的 Log File
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile(strLogFile)

其實這個功能跟我之前介紹的 ping commander很類似,只是我用WSH寫的,沒有 GUI 介面,而且多了個寄送 Log的功能。但是沒有支援 ping 多個目標的功能。

也許改天有空再改用 HTA來寫 GUI 介面的程式。

後記:

如果該程式的 strLocation最好使用英文,最好不要用中文,以免用戶端如果非繁中語系程式就會出問題!

自製動態 Public IP 檢查回報系統

有很多人(公司或個人),都是使用浮動 IP 的 ADSL,這導致 IT 人員進行遠端管理或維護時的困難。

坊間的解決方案多是使用 DDNS ,其他可以通報 IP 變動的工具大多都是要錢的...

其實這樣的程式也不難,要額外收費實在令人難以接受...

廢話不多說,底下就是我寫的WSH程式,

第一次執行後,會把你的 Public IP Address 寄到你指定的信箱,

之後每五分鐘會再 Check 一次 Public IP,如果IP 有變動,才會再寄信通知。

PS.該程式寄信並不需要你自己架Mail Service,可以在網路上找個 SMTP Server來用即可。


On Error Resume Next

strDynamicIP = "xxx.xxx.xxx.xxx"

' 這個網址可以替換成你自己喜好的查詢 IP 地址的網站
strURL="
http://briian.com/files/act/myip-widget.php"

Set objHTTP = CreateObject("MSXML2.XMLHTTP")

Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = True  
objRegEx.Pattern = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"

Set objEmail = CreateObject("CDO.Message")

while true
objHTTP.Open "GET", strURL, FALSE
objHTTP.Send

Set colMatches = objRegEx.Execute(objHTTP.ResponseText)

For Each strMatch in colMatches
  strPublicIP = strMatch.Value
Next

' 網頁內容沒有 IP Address,考慮換個網站吧
if colMatches.Count < 1 then
  WScript.Echo "IP Address Not Found !"
end if
' 如果抓出來的網頁只有一個 IP Address,而且跟之前抓的不一樣,表示 IP 有變動,要通知囉
if colMatches.Count = 1 and strDynamicIP <> strPublicIP then
  objEmail.From = "
寄信人信箱地址"
  objEmail.To = "
收件人信箱地址"
  objEmail.Subject = "Your Public IP : " & strPublicIP
  objEmail.Textbody = strPublicIP
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/smtpserver") = "SMTP Server的FQDN或IP"
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/sendusername") = "你的E-Mail帳號"
  objEmail.Configuration.Fields.Item ("
http://schemas.microsoft.com/cdo/configuration/sendpassword") = "你的e-Mail密碼"
  objEmail.Configuration.Fields.Update
  objEmail.Send
  strDynamicIP = strPublicIP
end if
' 如果抓出來的網頁內容,超過一個 IP Address,就要改程式去分析網頁囉
if colMatches.Count > 1 then
  WScript.Echo "Too Many IPs !"
end if

' 每隔 5 分鐘抓一次網頁,Check Public IP
wscript.sleep 300000
wend

將Exchange 2003 SPAM Mail按照日期歸檔#1(使用Windwos Script)

使用 Exchange 2003 的 IMF 功能時,

畢竟它還是會誤判,所以保險的作法是將 SPAM Mail 封存,

如果有漏信,再來 SPAM Mail Folder找漏信。

結果,太久沒去看 SPAM Mail Archive Folder,裡面累積了數十萬封廣告信,

每一封廣告信都是 .EML 檔案,純文字格式,可以用 Outlook Express 開啟閱讀。

重點是,在檔案總管一進入此目錄時,就因為檔案太多,造成系統無回應。

為了處理這個狀況,只好在命令提示字元模式下,以指令搬移檔案,但是這樣很花時間,

所以我寫了一支小程式,依照日期建立目錄,同時將每天的廣告信搬到該目錄下,

這樣就不會造成一個目錄底下有太多檔案,系統忙著讀取資訊而沒有回應。


' 取得昨天的日期
dtmYesterday = Date() - 1
' 將昨天的日期取出年份
strYear = left(dtmYesterday,4)
' 將昨天的日期取出月份

'  因為月份小於10時,不會補 0, 這樣目錄看起來會有點亂,所以稍微加工一下
if mid(dtmYesterday,7,1) = "/" then
strMonth = "0" & mid(dtmYesterday,6,1)
else
strMonth = mid(dtmYesterday,6,2)
end if
' 將昨天的日期取出日期

' 因為日期小於 10時,不會補零,這樣目錄看起來會有點亂,所以稍微加工一下
if mid(dtmYesterday,len(dtmYesterday)-1,1) = "/" then
strDay = "0" & right(dtmYesterday,1)
else
strDay = right(dtmYesterday,2)
end if
strYesterday = strYear & strMonth & strDay
' 以昨天的日期來建立目錄
ParentFolder = "E:\Exchsrvr\UCEArchive" 
set objShell = CreateObject("Shell.Application")
set objFolder = objShell.NameSpace(ParentFolder)
objFolder.NewFolder strYesterday
' 將檔名包含昨天日期的檔案,全數搬移到昨天日期的目錄下
Set objFSO = CreateObject("Scripting.FileSystemObject")
FileNamePatten = "ARCH_" & strYesterday & "*.EML"
objFSO.MoveFile "E:\Exchsrvr\UCEArchive\" & FileNamePatten , "E:\Exchsrvr\UCEArchive\" & strYesterday

' 這只是告知程式執行完畢的訊息,要不然完全沒有訊息,程式有沒有跑,有沒有完都不知道!
wscript.echo strYesterday & " Job is done !"