I need an AHK script which will check/compare an MD5 checksum value for a specified file.
Something like this:
'Does file "%userprofile%\appsettings\app.ini" have an MD5 checksum value A465564D654E56464025456F?
if YES
Msgbox "not changed"
if NO
filedelete, "%userprofile%\appsettings\app.ini"
Then:
filecopy, "%userprofile%\appsettings\app.kackup", "%userprofile%\appsettings\app.ini"
Exit script
I need this to be run manually - on demand, not a persistent script.
I prefer it to be an Autohotkey script, but if it is too complicated, powershell or batch script is fine too.
Thank you
One solution:
var:= ComObjCreate("WScript.Shell").Exec("cmd.exe /q /c CertUtil -hashfile %userprofile%/appsettings/app.ini MD5").StdOut.ReadAll()
outputArr := (StrSplit(var , "`r`n"))
out:=outputArr[2]
;MsgBox %out%
if(out=="A465564D654E56464025456F"){
Msgbox not changed
ExitApp
}
else{
MsgBox Different MD5- restoring...
filecopy, %userprofile%\appsettings\app.backup, %userprofile%\appsettings\app.ini, 1
ExitApp
}
See the full explanation of the MD5 hashing part here. In summary:
We can use the Windows CertUtil tool to find the MD5 hash sum and
Parse the output by StrSpliting it into different lines (The MD5 sum
itself will be on the second line).
The rest of the script is just some logic to check if the hash is the same as the one given (A465564D654E56464025456F), and if it is not, filecopy the .backup1 onto the .ini file. Note that we do not need to explicitly call filedelete if we give filecopy the ability to overwrite files.
1- I think that you might have meant a .backup file instead of a .kackup file, but I may be wrong. If you wanted a .kackup file, replace app.backup with app.kackup in the script.
Related
I have a powershell script that generates a report, and I have connected it to an io.filesystemwatcher. I am trying to improve the error handling capability. I already have the report generation function (which only takes in a filepath) within a try-catch loop that basically kills word, excel and powerpoint and tries again if it fails. This seems to work well but I want to embed in that another try-catch loop that will restart the computer and generate the report after reboot if it fails a second consecutive time.
I decided to try and modify the registry after reading this article: https://cmatskas.com/configure-a-runonce-task-on-windows/
my plan would be, within the second try-catch loop I will create a textfile called RecoveredPath.txt with the file path being its only contents, and then add something like:
Set-ItemProperty "HKLMU:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!RecoverReport' -Value "C:\...EmergencyRecovery.bat"
Before rebooting. Within the batch file I have:
set /p RecoveredDir=<RecoveredPath.txt
powershell.exe -File C:\...Report.ps1 %RecoveredDir%
When I try to run the batch script, it doesn't yield any errors but doesn't seem to do anything. I tried adding in an echo statement and it is storing the value of the text file as a variable but doesn't seem to be passing it to powershell correctly. I also tried adding -Path %RecoveredDir% but that yielded an error (the param in report.ps1 is named $Path).
What am I doing incorrectly?
One potential problem is that not enclosing %RecoveredDir% in "..." would break with paths containing spaces and other special chars.
However, the bigger problem is that using mere file name RecoveredPath.txt means that the file is looked for in whatever the current directory happens to be.
In a comment your state that both the batch file and input file RecoveredPath.txt are located in your desktop folder.
However, it is not the batch file's location that matters, it's the process' current directory - and that is most likely not your desktop when your batch file auto-runs on startup.
Given that the batch file and the input file are in the same folder and that you can refer to a batch file's full folder path with %~dp0 (which includes a trailing \), modify your batch file to look as follows:
set /p RecoveredDir=<"%~dp0RecoveredPath.txt"
powershell.exe -File C:\...Report.ps1 "%RecoveredDir%"
For instance, I am creating reboot scripts for about 400 servers to reboot every night. I already have the task scheduler portion done with a script.
What I need is, how to insert "shutdown /r /m \servername-001 /f" into a file called "servername-001_Reboot.bat".
and in the same script change the 001 to 002 into the next batch file and so on and so forth.
Unless someone has a more efficient way of doing an automated reboot schedule.
Have a variable $ServerNumber = 1 and inside your for-loop just keep incrementing it.
The filename for the batchfile can be made like so:
$filename = "servername-$( "{0:D3}" -f $ServerNumber )_Reboot.bat"
(Read here to learn more about formatting numbers in powershell)
Any variable including a string, let's call it $str, can be piped to any file:
$str | Out-File "path/to/file/$filename"
use the -Append flag if you want to append data to the file if it already exists (as opposed to overwriting it).
In command prompt - How do I export all the content of the screen to a text file(basically a copy command, just not by using right-clicking and the clipboard)
This command works, but only for the commands you executed, not the actual output as well
doskey /HISTORY > history.txt
If you want to append a file instead of constantly making a new one/deleting the old one's content, use double > marks. A single > mark will overwrite all the file's content.
Overwrite file
MyCommand.exe>file.txt
^This will open file.txt if it already exists and overwrite the data, or create a new file and fill it with your output
Append file from its end-point
MyCommand.exe>>file.txt
^This will append file.txt from its current end of file if it already exists, or create a new file and fill it with your output.
Update #1 (advanced):
My batch-fu has improved over time, so here's some minor updates.
If you want to differentiate between error output and normal output for a program that correctly uses Standard streams, STDOUT/STDERR, you can do this with minor changes to the syntax. I'll just use > for overwriting for these examples, but they work perfectly fine with >> for append, in regards to file-piping output re-direction.
The 1 before the >> or > is the flag for STDOUT. If you need to actually output the number one or two before the re-direction symbols, this can lead to strange, unintuitive errors if you don't know about this mechanism. That's especially relevant when outputting a single result number into a file. 2 before the re-direction symbols is for STDERR.
Now that you know that you have more than one stream available, this is a good time to show the benefits of outputting to nul. Now, outputting to nul works the same way conceptually as outputting to a file. You don't see the content in your console. Instead of it going to file or your console output, it goes into the void.
STDERR to file and suppress STDOUT
MyCommand.exe 1>nul 2>errors.txt
STDERR to file to only log errors. Will keep STDOUT in console
MyCommand.exe 2>errors.txt
STDOUT to file and suppress STDERR
MyCommand.exe 1>file.txt 2>nul
STDOUT only to file. Will keep STDERR in console
MyCommand.exe 1>file.txt
STDOUT to one file and STDERR to another file
MyCommand.exe 1>stdout.txt 2>errors.txt
The only caveat I have here is that it can create a 0-byte file for an unused stream if one of the streams never gets used. Basically, if no errors occurred, you might end up with a 0-byte errors.txt file.
Update #2
I started noticing weird behavior when writing console apps that wrote directly to STDERR, and realized that if I wanted my error output to go to the same file when using basic piping, I either had to combine streams 1 and 2 or just use STDOUT. The problem with that problem is I didn't know about the correct way to combine streams, which is this:
%command% > outputfile 2>&1
Therefore, if you want all STDOUT and STDERR piped into the same stream, make sure to use that like so:
MyCommand.exe > file.txt 2>&1
The redirector actually defaults to 1> or 1>>, even if you don't explicitly use 1 in front of it if you don't use a number in front of it, and the 2>&1 combines the streams.
Update #3 (simple)
Null for Everything
If you want to completely suppress STDOUT and STDERR you can do it this way. As a warning not all text pipes use STDOUT and STDERR but it will work for a vast majority of use cases.
STD* to null
MyCommand.exe>nul 2>&1
Copying a CMD or Powershell session's command output
If all you want is the command output from a CMD or Powershell session that you just finished up, or any other shell for that matter you can usually just select that console from that session, CTRL + A to select all content, then CTRL + C to copy the content. Then you can do whatever you like with the copied content while it's in your clipboard.
Just see this page
in cmd type:
Command | clip
Then open a *.Txt file and Paste. That's it. Done.
If you are looking for each command separately
To export all the output of the command prompt in text files. Simply follow the following syntax.
C:> [syntax] >file.txt
The above command will create result of syntax in file.txt. Where new file.txt will be created on the current folder that you are in.
For example,
C:Result> dir >file.txt
To copy the whole session, Try this:
Copy & Paste a command session as follows:
1.) At the end of your session, click the upper left corner to display the menu.
Then select.. Edit -> Select all
2.) Again, click the upper left corner to display the menu.
Then select.. Edit -> Copy
3.) Open your favorite text editor and use Ctrl+V or your normal
Paste operation to paste in the text.
If your batch file is not interactive and you don't need to see it run then this should work.
#echo off
call file.bat >textfile.txt 2>&1
Otherwise use a tee filter. There are many, some not NT compatible. SFK the Swiss Army Knife has a tee feature and is still being developed. Maybe that will work for you.
How about this:
<command> > <filename.txt> & <filename.txt>
Example:
ipconfig /all > network.txt & network.txt
This will give the results in Notepad instead of the command prompt.
From command prompt Run as Administrator. Example below is to print a list of Services running on your PC run the command below:
net start > c:\netstart.txt
You should see a copy of the text file you just exported with a listing all the PC services running at the root of your C:\ drive.
If you want to output ALL verbosity, not just stdout. But also any printf statements made by the program, any warnings, infos, etc, you have to add 2>&1 at the end of the command line.
In your case, the command will be
Program.exe > file.txt 2>&1
I am doing a batch scripting assignment where I have to call one script from inside another. I need the script to run the second script no matter where my lecturer saves these scripts. How would I do this. Is there some way to find the path of script inside the script and use that to execute the file. Any help would be great. I think I need to use %'s but i'm not sure.
The name of the script is Hello World.bat.
How would I copy Hello World.bat to the C:\ if I don't know which directory the lecturer has placed it in. what command/s would I use so that the copy would work regardless of the scripts location.
I don't see the "DOS" tag, but I'll assume that it is for now. If you want the entire path, you can get it by doing this:
echo %cd%
If you want just the last folder, this works (inside a .bat file):
for %%* in (.) do #echo %%~n*
Note that from the command line, the above command will work with single %'s:
for %* in (.) do #echo %~n*
If the script you are executing is calling other scripts in the SAME folder location, you can prefix the path statement with "%~dp0" or "%~dps0" but do not put a backslash between that and the name of the script you are calling. In other words, if script1.bat is calling script2.bat in the same folder, the statement in script1.bat would refer to "%~dp0script2.bat"
sorry about batch files, am not familiar, but in nix shell, there is the locate command which can return the path of the file , if you know the filename exactly and the name is unique.
like
name=$(locate filname)
I am calling a FTP file from DOS, which holds ftp set of commands as follows:
ftp -s:ftpcmd1.txt
Now, the change requirement says, file is to be called multiple times with different file paths.
so, I need to write above statement, each time passing new file path as argument with FTP filename and writing something like "%1" in command inside ftp-file. Please help me with same. How do I do it.
Thanks.
I dont know if we can pass parameter to ftp script (atleast in DOS). But in the above case dynamically written out ftp script file would help. Small bat file which would do that is like below.
echo "user username pwd">ftpcmd1.txt
echo "bin">>ftpcmd1.txt
echo "put %1">>ftpcmd1.txt
echo "bye">>ftpcmd1.txt
ftp -n -i -v servername<ftpcmd1.txt
If you call this bat file with any file name as the first command line argument, it would transfer the file to target servername. Hope this is what you are looking for.