Is it possible to create notification that lets you know if something was modified, created, etc?
#echo off
setlocal EnableDelayedExpansion
set "emailUserName="
set "emailPassword="
set "target="
REM set "target="
REM set "target="
set "subject="
FOR %%G IN (*) DO attrib -A "%%G"
:loop
set "body="
FOR %%G IN (*) DO (
attrib "%%G" | findstr /B /L A 1>nul
if !errorlevel! equ 0 (
echo "%%G"
set "body=!body!^<br ^/^>%%G"
attrib -A "%%G"
)
) 2>nul
if not "%body%"=="" echo sending email
if not "%body%"=="" set "body=!body!"
if not "%body%"=="" powershell.exe -command "Send-MailMessage -From '!emailUserName!' -to '!target!' -Subject '!subject!' -Body '!body!' -BodyAsHtml -SmtpServer 'smtp.gmail.com' -port '587' -UseSsl -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('!emailUserName!', (ConvertTo-SecureString -String '!emailPassword!' -AsPlainText -Force)))"
cls
goto :loop
emailUserName - from which email it will be send
emailPassword - enter password
target - to whom it will be sent
subject - subject
You need to create bash script and run it at the folder where files will be created/modified. As soon as file has been create or modified it will send an email to your target.
For simple notifications, you can use Directory Change Notifications. There's already a quite big and comprehensive example on the page and I will not write another example.
By simple notification I mean file/folder create and modification for a specific folder which shouldn't change very often.
If you want to handle system wide file/folder notification, I would suggest you to write a file filter driver.
In my opinion SharePoint 2016, 2013, or 2010 fixes your problem :
https://support.office.com/en-us/article/create-an-alert-to-get-notified-when-a-file-or-folder-changes-in-sharepoint-e5a79e7b-a146-46da-a9ef-d65409ba8918
Related
I have been trying to make this work for longer than I care to admit but for some reason I cannot figure it out. I usually work with Linux/Unix.
I simply want to search a directory for all instances where a filename matches a string.
Some things I have tried:
dir /s "/path/to/Test*"
dir /s/b "C:/path/to/Test*"
Additionally, I am hoping to return something that can easily be imported into an array. Something without unnecessary information. All I need Is the path or at the very least the filename for each file matched.
Edit: I dont want information like this (if possible)
Volume in drive C is OS
Volume Serial Number is...
Edit: Test* is intended to indicate all filenames beginning with Test. So TestA, TestB, & TestC should all match.
The same commands work on Linux, Mac, and Windows. http://github.com/PowerShell/PowerShell/
PS C:\src> (Get-ChildItem -Recurse -File -Path 'C:/src/d2' -Filter 'test*').FullName
C:\src\d2\test.bat
C:\src\d2\test.ps1
C:\src\d2\test.sql
C:\src\d2\test.txt
C:\src\d2\copyt\test.txt
Using command aliases, it can be shorter for interactive use. But, aliases are not a good practice for scripts.
PS C:\src> (ls -r -file 'C:/src/d2/test*').FullName
C:\src\d2\test.bat
C:\src\d2\test.ps1
C:\src\d2\test.sql
C:\src\d2\test.txt
C:\src\d2\copyt\test.txt
If you want an array, this will make one.
PS C:\src> $files = (ls -r -file 'C:/src/d2/test*').FullName
PS C:\src> $files.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Replace directory separators with -replace.
(Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/'
Join them to a single line with -join. This join uses a COMMA. Note that if the join uses a COLON in *NIX-style, it will not work well on Windows.
PS C:\src> (Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/' -join (',')
C:/src/d2/test.bat,C:/src/d2/test.ps1,C:/src/d2/test.sql,C:/src/d2/test.txt,C:/src/d2/copyt/test.txt
If you need a PATH-style separator, use:
(Get-ChildItem -Recurse -Path 'C:/src/d2' -Filter 'test.*').FullName -replace '\\','/' -join ([IO.Path]::PathSeparator)
I've just been searching for all files, called "test.*" all over my C:-drive, using this simple command:
dir /S C:\test*
Although I just mention the directory C:\, the /S makes sure all subfolders are used too. In top of that, there are no double quotes, as you can see.
Does this solve your issue?
Sorry, I didn't see that you're used working with UNIX/Linux, so here I have an approach you'll prefer:
forfiles /P C:\ /S /M test* /C "cmd /c echo #path"
This does the following:
/P C:\ Start looking in C:\
/S Search through subdirectories
/M test* Filename looks like "test*"
/C <cmd> When found, launch <cmd>
"cmd /c echo #path" Echo (write to output) the complete path of the found file or directory
This will give you a list of files and directories, written as full paths, something like:
"C:\Octave\Octave-5.2.0\mingw64\bin\test-libiberty.exe"
"C:\Octave\Octave-5.2.0\mingw64\bin\test-lua.exe"
"C:\Octave\Octave-5.2.0\mingw64\bin\test-tinyxml.exe"
"C:\Octave\Octave-5.2.0\mingw64\include\llvm\Testing" <-- this is a directory
"C:\Octave\Octave-5.2.0\mingw64\include\wx-3.0\wx\testing.h"
...
Which resembles a lot the typical UNIX/Linux results, you're used to.
More information about forfiles can be found, launching forfiles /?.
Based upon your statement, "I am hoping to return something that can easily be imported into an array", I'd assume you're probably looking for something more like this:
#Echo Off
Rem Ensure that extensions are enabled (required for SET and FOR commands)
SetLocal EnableExtensions
Rem Ensures that there are no existing variables in the environment with names beginning with file[
For /F "Delims==" %%G In ('" Set file[ 2> NUL "') Do Set "%%G="
Rem Gets every file matching the glob test* in the tree rooted at "C:\path\to"
Rem and defines an incremented variable name for each, beginning at %file[1]%
For /F "Tokens=1,* Delims=]" %%G In (
'" Dir /B /S /A-D "C:\path\to\test*" 2> NUL | "%__AppDir__%find.exe" /N /V "" "'
) Do Set "file%%G]=%%H"
Rem An example line to show you all of the variables you have now defined
Set file[ 2> NUL
Rem Pause the script to ensure that you have been able to read any output
Pause
Rem An example line to show you all the first defined variable value
Echo=%file[1]%
Rem Pause the script to ensure that you have been able to read any output
Pause
...and here it is without the Remarks:
#Echo Off
SetLocal EnableExtensions
For /F "Delims==" %%G In ('" Set file[ 2> NUL "') Do Set "%%G="
For /F "Tokens=1,* Delims=]" %%G In (
'" Dir /B /S /A-D "C:\path\to\test*" 2> NUL | "%__AppDir__%find.exe" /N /V "" "'
) Do Set "file%%G]=%%H"
Set file[ 2> NUL
Pause
Echo=%file[1]%
Pause
Don't forget to change C:\path\to\test* as required for your specific location and glob.
the for loop in windows batch console hangs and does not work while processing huge files of 10 gb but works with smaller files less than 1 gb. Eg
FOR /F "delims=]" %%A IN (dummy.txt) DO (
...code...
)
I need a batch script that will read first 10 lines of a code from a 10 gb Informatica session log file efficiently. Is there any way to read huge files using batch programming ??
Try this:
#echo off
setlocal EnableDelayedExpansion
rem Read first 10 lines
(for /L %%i in (1,1,10) do set /P "line[%%i]=") < dummy.txt
rem Process them
for /L %%i in (1,1,10) do (
echo Line %%i- !line[%%i]!
FOR /F "delims=]" %%A IN ("!line[%%i]!") DO (
...code...
)
)
PS - I would bet this method run much faster than the PowerShell one! ;)
I suggest you use powershell for this. there are 2 basic methods:
Open powershell. Start, run(search), poweshell.exe. Then cd to the relevant directory and then run:
Get-Content dummy.txt | Select-Object -first 10
or save the above in a file with a .ps1 extenion and simply run it from there.
If you still want to use it from within a batch file, simply make some additions like below and save as a .bat or .cmd file.
powershell -command "& {Get-Content dummy.txt | Select-Object -first 10}"
If you have powershell 3 or later, you can use the new head function built-in.
from batch:
powershell -command "& {Get-Content dummy.txt -Head 10}"
Or again as pure powershell:
Get-Content dummy.txt -Head 10
To read from a huge file you can use a for /F loop and abort it using goto:
#echo off
set /A "COUNT=0, LIMIT=10"
for /F usebackq^ delims^=^ eol^= %%L in ("huge.txt") do (
set /A "COUNT+=1" & set "LINE=%%L"
setlocal EnableDelayedExpansion
rem // Do something with the current line:
echo Line !COUNT!: !LINE!
if !COUNT! geq !LIMIT! goto :QUIT
endlocal
)
:QUIT
The greatest possible length of each line is about 8190 bytes or characters. Empty lines are ignored by for /F and therefore not counted.
I am attempting to remove Lenovo Fingerprint Manager Pro from a dozen or so Windows 8.1 machines due to the recurring vulnerabilities of the software.
I wrote the following batch file in order to remove it. While it worked on my initial test, it has failed upon subsequent attempts.
I was looking to see where the error is, and if someone may have a better way about going about this?
#echo off
REM This file will remove the Lenovo Finger print scanner and the relevant registry entries.
DEL "C:\windows\Installer\fa4f.msi"
set folder="C:\Program Files\Lenovo\Fingerprint Manager Pro"
cd /d %folder%
for /F "delims=" %%i in ('dir /b') do (rmdir "%%i" /s/q || del "%%i" /s/q)
cd /d %folder%
cd ..
rmdir %folder%
REG DELETE HKEY_CLASSES_ROOT\CLSID\{940B1CC9-013F-468e-BBBF-4A975461F120} /f
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Lenovo\Fingerprint Software /f
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{314FAD12-F785-4471-BCE8-AB506642B9A1} /f
ECHO Lenovo Fingerprint Scanner Removed Successfully.
In powershell you can get the program as an object and call uninstall on that object:
$App = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "Software Name"}
$App.uninstall()
The if you really want to cleanup registry and all that fun stuff you can do that afterwards.
Is there a quick way to identify whether a computer is member of domain or workgroup using batch script? If it is the member of domain, What is the domain's name?
Finally I was able to find it with powershell and capture it output in batch variable.
Following is the code
#echo off
REM Bellow logic is to identify "Computer membership"? True=Member of domain | False=Member of Workgroup
for /f %%a in ('powershell "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"') do set ComMem=%%a
echo %ComMem%
If %ComMem% Equ True (
GoTo Domainmember
) Else (
GoTo WorkgroupMember
)
REM Bellow logic is will find Domain / Workgroup Name
:Domainmember
for /f %%f in ('powershell "(Get-WmiObject Win32_ComputerSystem).Domain"') do set MemNme=%%f
Pause
GoTo End
:WorkgroupMember
for /f %%f in ('powershell "(Get-WmiObject Win32_ComputerSystem).Workgroup"') do set MemNme=%%f
:End
Echo %MemNme%
pause
I'm running automation testing on Windows (windows 10 and 2012), and one of the requirements of the automation is that ALL users need to be logged off. I have a chance to do this after deployment. I kind of see this page give an answer, but after I tried query session, I see it gives even services and rdp-tcp sessions... but I don't want to stop any service...
Any suggestion?
This solution is based on the previous answer but this one will close all sessions (even disconnected sessions). Unfortunately, the text format of each line returned by the 'query session' command can be difficult to parse. As you can see in the next screenshot, the username may be empty and in this example, if you use tokens=3, you will get the username instead of the ID for the user compil.
The problem is that you cant logoff a disconnected user with his username. To circumvent this problem, we use 2 for loops to get the session name and id (depending on the line format), and then we keep only the numeric values to send the logoff command and logoff also the disconnected sessions.
#echo off
for /f "skip=2 tokens=2,3 delims= " %%a in ('query session') DO (
echo %%a|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%a
)
echo %%b|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%b
)
)
The page you linked has the correct answer. Except that in Windows 2012 / 10 you should use skip=2 instead of 1. This way you will skip the 'services' line.
So your batch file will look like this:
query session >session.txt
for /f "skip=2 tokens=3," %%i in (session.txt) DO logoff %%i
del session.txt
We use this to log off all rdp sessions with the exception of the administrator. Could be tweaked as needed.
#echo off
:: Log off Active Users
query session | findstr "rdp, Active" | findstr /V "dministrator" >sessionActive.txt
for /f "tokens=3" %%i in (sessionActive.txt) DO logoff %%i
del sessionActive.txt
:: Log off Disconnected Users
query session | findstr "Disc" | findstr /V "dministrator, services" >sessionDisc.txt
for /f "tokens=2" %%i in (sessionDisc.txt) DO logoff %%i
del sessionDisc.txt
Note: "file.txt" contain computer name for each line.
for /f "tokens=*" %%i in ("*\file.txt") do (
psexec \\%%i -u domain\user -p password logoff console
)
Before using this code, you must download PsTools by this link:
https://download.sysinternals.com/files/PSTools.zip
https://learn.microsoft.com/vi-vn/sysinternals/downloads/psexec
Then extract PsTools archive => Copy all file => Paste to "*:\Windows\System32" => Installation Complete
use eol=> to skip active user
#echo off
query session > session.txt
::quser > session.txt
for /f "skip=2 eol=> tokens=2,3 delims= " %%G in (session.txt) DO (
echo %%G|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%G & echo logoff disconnect user %%G
)
echo %%H|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%H & echo logoff active user %%H
)
)
del session.txt