?
Solved

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

Posted on 2010-08-19
26
Medium Priority
?
798 Views
Last Modified: 2012-05-10
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
0
Comment
Question by:bsharath
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 8
  • 4
26 Comments
 
LVL 12

Expert Comment

by:jostrander
ID: 33475226
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

0
 
LVL 13

Expert Comment

by:soostibi
ID: 33475254
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

0
 
LVL 12

Expert Comment

by:jostrander
ID: 33475288
Nice soostibi, I didn't even think to use __InstanceCreationEvent on Win32_Share.  
0
Prepare for your VMware VCP6-DCV exam.

Josh Coen and Jason Langer have prepared the latest edition of VCP study guide. Both authors have been working in the IT field for more than a decade, and both hold VMware certifications. This 163-page guide covers all 10 of the exam blueprint sections.

 
LVL 11

Author Comment

by:bsharath
ID: 33477073
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?
0
 
LVL 12

Expert Comment

by:jostrander
ID: 33477173
Yeah, it loops continuously, checking every 5 seconds.
0
 
LVL 11

Author Comment

by:bsharath
ID: 33477474
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
0
 
LVL 12

Expert Comment

by:jostrander
ID: 33477713
Maybe a permissions error or something.  Comment out the ON ERROR RESUME NEXT lines and see what happens.
0
 
LVL 11

Author Comment

by:bsharath
ID: 33477751
I did comment both places still no errors show...
0
 
LVL 12

Expert Comment

by:jostrander
ID: 33477999
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
0
 
LVL 11

Author Comment

by:bsharath
ID: 33478051
Still no reply at all no email or msgbox
0
 
LVL 11

Author Comment

by:bsharath
ID: 33478388
Joe i think as you stated could be the SMTP issue.
Can you change the code to use outlook.
This is one code that worked
http://www.experts-exchange.com/Programming/Languages/Q_26409483.html?cid=239#a33465180
0
 
LVL 12

Expert Comment

by:jostrander
ID: 33478705
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

0
 
LVL 11

Author Comment

by:bsharath
ID: 33481848
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.
0
 
LVL 12

Accepted Solution

by:
jostrander earned 2000 total points
ID: 33485166
Email subs removed, try this out:
arrComputers = Array("computer001","computer002","computer003","computer004","computer005")

Set WshShell=CreateObject("Wscript.Shell")
'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If

SourceDir=replace(wscript.scriptfullname,wscript.scriptname,"")
strLogFile=SourceDir & "results.txt"

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..."
wscript.echo

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 LogIt 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)
			LogIt strComputer,strName,strPath,"removed"
			oDict.Remove key
		End If
	Next
		
End Sub


Sub LogIt(strHost,strShare,strPath,strAction)
	
	wscript.echo "-------------------------------------------------------"
	wscript.echo "Share " & strAction & " on Host:  " & strHost & vbCrLf & _
						vbTab & "Share:" & vbTab & strShare & vbCrLf & _
						vbTab & "Path: " & vbTab & strPath & vbCrLf

	Set fso=CreateObject("Scripting.FileSystemObject")
	If NOT fso.FileExists(strLogFile) then
		WriteHeaders=True
	Else
		WriteHeaders=False
	End If
	Set oFile=fso.OpenTextFile(strLogFile,8,True)
	If WriteHeaders=True then oFile.WriteLine "Host,Action,Share,Path"
	oFile.WriteLine strHost & "," & strAction & "," & strShare & "," & strPath
	oFile.Close

End Sub

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 33485253
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
0
 
LVL 12

Expert Comment

by:jostrander
ID: 33486041
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?

0
 
LVL 11

Author Comment

by:bsharath
ID: 33486603
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
0
 
LVL 13

Expert Comment

by:soostibi
ID: 33492435
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.
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494639
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.
0
 
LVL 13

Expert Comment

by:soostibi
ID: 33494654
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.
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494690
I get the same message as posted here
ID: 33477073
0
 
LVL 13

Expert Comment

by:soostibi
ID: 33494753
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.
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494762
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...
0
 
LVL 11

Author Comment

by:bsharath
ID: 33679915
Thanks a lot Joe
Sorry for the delay in accepting
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
Windows 10 came with  a lot of built in applications, Some organisations leave them there, some will control them using GPO's. This Article is useful for those who do not want to have any applications in their image (example:me).
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question