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
777 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
  • 13
  • 8
  • 4
26 Comments
 
LVL 12

Expert Comment

by:jostrander
Comment Utility
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
Comment Utility
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
Comment Utility
Nice soostibi, I didn't even think to use __InstanceCreationEvent on Win32_Share.  
0
 
LVL 11

Author Comment

by:bsharath
Comment Utility
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 11

Author Comment

by:bsharath
Comment Utility
0
 
LVL 12

Expert Comment

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

Author Comment

by:bsharath
Comment Utility
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
Comment Utility
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
Comment Utility
I did comment both places still no errors show...
0
 
LVL 12

Expert Comment

by:jostrander
Comment Utility
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
Comment Utility
Still no reply at all no email or msgbox
0
 
LVL 11

Author Comment

by:bsharath
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 12

Expert Comment

by:jostrander
Comment Utility
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
Comment Utility
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 500 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
I get the same message as posted here
ID: 33477073
0
 
LVL 13

Expert Comment

by:soostibi
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks a lot Joe
Sorry for the delay in accepting
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Journaling in Office365 5 30
Powershell Script Error Handling 7 31
Problem to page 4 16
Modify Policy using PowerShell 6 0
This is a PowerShell web interface I use to manage some task as a network administrator. Clicking an action button on the left frame will display a form in the middle frame to input some data in textboxes, process this data in PowerShell and display…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now