Link to home
Start Free TrialLog in
Avatar of bsharath
bsharathFlag for India

asked on

Powershell or Vbs script to monitor 5 file servers and if any new share appears then email the details.

Hi,

Powershell or Vbs script to monitor 5 file servers and if any new share appears then email the details.

Only if change is there email.
Like New share created,Share removed

Regards
Sharath
Avatar of jostrander
jostrander
Flag of United States of America image

Hey Sharath, give this a shot:
arrComputers = Array("computer123","computer456")
strEmailServer="smtpserver123"
strEmailFrom="Share Monitor <noreply@wherever.com>"
strEmailTo="Joe Ostrander <jostrander@somewhere.com>"

FirstRun=True
set oDict=CreateObject("Scripting.Dictionary")

Do
	CheckShares
	wscript.sleep 5000
Loop

Sub CheckShares
	ON ERROR RESUME NEXT
	For each strComputer in arrComputers
		Set objWMIService = GetObject("winmgmts:" _
			& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
		
		Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
		
		For each objShare in colShares
			If NOT oDict.Exists(strComputer & "---" & objShare.Name) Then
				oDict.Add strComputer & "---" & objShare.Name,objShare.Path
				If FirstRun=False then SendMail strComputer,objShare.Name,objShare.Path
			End If
		Next
	Next
	FirstRun=False
End Sub


Sub SendMail(strHost,strShare,strPath)
	ON ERROR RESUME NEXT		
	Set objEmail = CreateObject("CDO.Message")
	objEmail.From = strEmailFrom
	objEmail.To = strEmailTo
	objEmail.Subject = "Share added to host:  " & strHost
	objEmail.Textbody = "Host: " & vbTab & strHost & vbCrLf & _
						"Share:" & vbTab & strShare & vbCrLf & _
						"Path: " & vbTab & strPath
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strEmailServer
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
	objEmail.Configuration.Fields.Update
	objEmail.Send
End Sub

Open in new window

Here you are!
$PSEmailServer = "yoursmtpserver.yourdomain.local"
$computers = "compueter1", "compueter2", "compueter3", "compueter4", "compueter5"

$wmicreationquery = "select * from __InstanceCreationEvent within 1 where TargetInstance ISA 'Win32_Share'"
$wmideletionquery = "select * from __InstanceDeletionEvent within 1 where TargetInstance ISA 'Win32_Share'"

$computers | %{
	Register-WmiEvent -ComputerName $_ -Query $wmicreationquery  -Action {
		$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "domain\user-with-relay-permissions",
			(Convertto-SecureString "yourpassword" -force -asplaintext)

		Send-MailMessage -To youremail@yourdomain.com -From "wmi-$($env:computername)@yourdomain.com" -Subject "Share created" `
		-body "Share is created named $($eventargs.NewEvent.TargetInstance.name), target $($eventargs.NewEvent.TargetInstance.path)" `
		-Credential $cred
	}

	Register-WmiEvent -ComputerName $_ -Query $wmideletionquery  -Action {
		$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "domain\user-with-relay-permissions",
			(Convertto-SecureString "yourpassword" -force -asplaintext)

		Send-MailMessage -To youremail@yourdomain.com -From "wmi-$($env:computername)@yourdomain.com" -Subject "Share deleted" `
		-body "Share is created named $($eventargs.NewEvent.TargetInstance.name), target $($eventargs.NewEvent.TargetInstance.path)" `
		-Credential $cred
	}
}

Open in new window

Nice soostibi, I didn't even think to use __InstanceCreationEvent on Win32_Share.  
Avatar of bsharath

ASKER

Joe
will the script keep running and when created will it trigger an email. How much time does it check?

Soostibi

I get this

Id              Name            State      HasMoreData     Location             Command
--              ----            -----      -----------     --------             -------
1               01a1650d-60d... NotStarted False                                ...
2               bd957073-d5c... NotStarted False                                ...
3               aaaa696c-3b8... NotStarted False                                ...
4               d7836ef8-326... NotStarted False                                ...

I changed 2 places my email address and the exchange server name and the machine names. is there anything else i need to change?
Yeah, it loops continuously, checking every 5 seconds.
Joe i set the server,Computers,from and To email address and it does not email yet.
I have created a share and removed a share but no mail
Maybe a permissions error or something.  Comment out the ON ERROR RESUME NEXT lines and see what happens.
I did comment both places still no errors show...
I remember we had problems with SMTP email scripts in your environment before... not sure if your email server required authentication or what.

As a test, underneath:
Sub SendMail(strHost,strShare,strPath)

add this:
msgbox strHost & vbCrLf & strShare & vbCrLf & strPath
Still no reply at all no email or msgbox
Try this out.  I modified to use instancecreationevent like Soostibi did and I added the Outlook email.  
I think Soostibi's script is nicer, but see if this works for you.  I'm not able to test the Outlook part at the moment, so I'll have to rely on you.


arrComputers = Array("computer001","computer002","computer003","computer004","computer005")
strEmailServer="smtpserver123"
strEmailFrom="Share Monitor <noreply@wherever.com>"
strEmailTo="Joe Ostrander <jostrander@somewhere.com>"


FirstRun=True
set oDict=CreateObject("Scripting.Dictionary")
set oDict2=CreateObject("Scripting.Dictionary")

'Create Dictionary of current shares
CheckSharesAdded

'Create Event Triggers
For each strComputer in arrComputers
	Set objWMIServices = GetObject("winmgmts:" & _
		"{impersonationLevel=impersonate, (security)}!\\" & strComputer & "\root\cimv2")
	
	Set objSinkCreate = WScript.CreateObject("WbemScripting.SWbemSink","CREATE_")
	Set objSinkDelete = WScript.CreateObject("WbemScripting.SWbemSink","DELETE_")
	objWMIServices.ExecNotificationQueryAsync objSinkCreate,"select * from __instancecreationevent " & _ 
		"within 1 where TargetInstance isa 'Win32_Share'"
	objWMIServices.ExecNotificationQueryAsync objSinkDelete,"select * from __instancedeletionevent " & _ 
		"within 1 where TargetInstance isa 'Win32_Share'"
Next

'wscript.echo "Waiting for events..."

Do
wscript.sleep 1000	
Loop

Sub CREATE_OnObjectReady(objObject, objAsyncContext)
    'WScript.Echo (objObject.TargetInstance.name)
    'WScript.Echo (objObject.TargetInstance.path)
    'WScript.Echo objObject.GetObjectText_() 
    CheckSharesAdded
End Sub

Sub DELETE_OnObjectReady(objObject, objAsyncContext)
    CheckSharesRemoved
End Sub

Sub CheckSharesAdded
	ON ERROR RESUME NEXT
	For each strComputer in arrComputers
		
		Set objWMI = GetObject("winmgmts:" _
			& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
		
		Set colShares = objWMI.ExecQuery("Select * from Win32_Share")
		
		'Check for added shares
		For each objShare in colShares
			If NOT oDict.Exists(strComputer & "---" & objShare.Name) Then
				oDict.Add strComputer & "---" & objShare.Name,objShare.Path
				If FirstRun=False then SendMail strComputer,objShare.Name,objShare.Path,"added"
			End If
		Next
				
	Next
	FirstRun=False
End Sub

Sub CheckSharesRemoved
	ON ERROR RESUME NEXT

	oDict2.RemoveAll
	
	For each strComputer in arrComputers
		
		Set objWMI = GetObject("winmgmts:" _
			& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
		
		Set colShares = objWMI.ExecQuery("Select * from Win32_Share")
		
		For each objShare in colShares
			oDict2.Add strComputer & "---" & objShare.Name,objShare.Path
		Next
	Next
	
	'Check for removed shares
	For each key in oDict.Keys
		If NOT oDict2.Exists(key) then
			strComputer=split(key,"---")(0)
			strName=split(key,"---")(1)
			strPath=oDict(key)
			SendMail strComputer,strName,strPath,"removed"
			oDict.Remove key
		End If
	Next
		
End Sub

Sub SendMailOLD(strHost,strShare,strPath,strMode)
	'wscript.echo strHost & "," & strShare & "," & strPath & "," & strMode
	ON ERROR RESUME NEXT		
	Set objEmail = CreateObject("CDO.Message")
	objEmail.From = strEmailFrom
	objEmail.To = strEmailTo
	objEmail.Subject = "Share " & strMode & " on host:  " & strHost
	objEmail.Textbody = "Host: " & vbTab & strHost & vbCrLf & _
						"Share:" & vbTab & strShare & vbCrLf & _
						"Path: " & vbTab & strPath
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strEmailServer
	objEmail.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
	objEmail.Configuration.Fields.Update
	objEmail.Send
End Sub

Sub SendMail(strHost,strShare,strPath,strMode)
	'wscript.echo strHost & "," & strShare & "," & strPath & "," & strMode
	
	Set ol = WScript.CreateObject("Outlook.Application")
	Set ns = ol.getNamespace("MAPI")
	ns.logon "","",true,false
	Set newMail = ol.CreateItem(olMailItem)
	newMail.Subject = "Share " & strMode & " on host:  " & strHost
	newMail.Body = "Host: " & vbTab & strHost & vbCrLf & _
						"Share:" & vbTab & strShare & vbCrLf & _
						"Path: " & vbTab & strPath & vbCrLf

	' validate the recipient, just in case...
	Set myRecipient = ns.CreateRecipient(strEmailTo)
	myRecipient.Resolve
	If Not myRecipient.Resolved Then
	   MsgBox "unknown recipient"
	Else
	   newMail.Recipients.Add(myRecipient)
	   newMail.Send
	End If

	Set ol = Nothing

End Sub

Open in new window

Hi Joe does not work

Can i have a way to log the details into a txt file in the script directory. So we know its working and only email part has issues.
ASKER CERTIFIED SOLUTION
Avatar of jostrander
jostrander
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No Joe just says waiting

after i ran the script
i went to 1 file server and removed a share and added a share and no results
Not sure... is this Win2K?  If so, I may need to redo some things.

I just tested again on XP, Win2003 Server and Win7 OK.

You have the remote servers specified in arrComputers, right?

Joe it does work sorry had a space on the machine name
This works too
ID: 33478705

But when email is sent it asks for the accept \deny box the security one.

Can i exclude that. i want it to open outlook send the email without any security warnings
You have to change
- the email server name in line 1,
- computer names in line 2,
- user name that has relay rights on email server in line 9
- this user's password in line 10
- the same user and password in lines 18-19
- the To and From addresses in lines 12 and 21.
soostibi
I have the relay bloocked. So need helpp with a way to use outlook thats configured as the means to send email. Only To will be mentioned.
Actually, by default, all domain users have relay rights on Exchange Servers. So if you use correct domain\username and password combination it should work. If it does not, then it's much simlier to set it on Exchange than send mail by Outlook.
I get the same message as posted here
ID: 33477073
It is normal. It is the indication that the jobs are created. You must not close the powershell window after that, as the script is running in the background.
Thanks it does work. I want the script running but the windows after close also should run.
I want to have the script added as a scheduled task if not that triggers every 30 min or so...
Thanks a lot Joe
Sorry for the delay in accepting