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
LVL 11
bsharathAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jostranderCommented:
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
soostibiCommented:
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
jostranderCommented:
Nice soostibi, I didn't even think to use __InstanceCreationEvent on Win32_Share.  
0
Hey MSSPs! What's your total cost of ownership?

WEBINAR: Managed security service providers often deploy & manage products from a variety of solution vendors. But is this really the best approach when it comes to saving time AND money? Join us on Aug. 15th to learn how you can improve your total cost of ownership today!

bsharathAuthor Commented:
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
jostranderCommented:
Yeah, it loops continuously, checking every 5 seconds.
0
bsharathAuthor Commented:
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
jostranderCommented:
Maybe a permissions error or something.  Comment out the ON ERROR RESUME NEXT lines and see what happens.
0
bsharathAuthor Commented:
I did comment both places still no errors show...
0
jostranderCommented:
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
bsharathAuthor Commented:
Still no reply at all no email or msgbox
0
bsharathAuthor Commented:
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
jostranderCommented:
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
bsharathAuthor Commented:
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
jostranderCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
bsharathAuthor Commented:
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
jostranderCommented:
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
bsharathAuthor Commented:
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
soostibiCommented:
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
bsharathAuthor Commented:
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
soostibiCommented:
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
bsharathAuthor Commented:
I get the same message as posted here
ID: 33477073
0
soostibiCommented:
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
bsharathAuthor Commented:
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
bsharathAuthor Commented:
Thanks a lot Joe
Sorry for the delay in accepting
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming Languages-Other

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.