RunOnceEx - Reboot System after each Installation - windows-xp

Is there any way I can reboot my computer after each component installation specified in RunOnceEx.CMD file?
I am creating a unattended setup disk for windows XP which would install some default software after installing windows on the system. I am using RunOnceEx.cmd file to define the software that needs to be installed, what I want is to reboot my the system after installation of each software.
Thanks and regards,

Yep there is. Although it's not a supported feature. I do something similar.
This might not be the the fanciest solution but it works reliably. The key is to stop the RunOnceEx process (rundll32.exe) before commencing the reboot procedure. If it's not stopped, Windows will stop all processes before shutting down in an unknown order. And if that order means killing our "Reboot" process before killing the RunOnceEx process it will continue on the next item on the RunOnceEx list before being killed (and thus aborted, which is not what we want).
The simple answer, add a reboot key that kills the RunOnceEx process and then reboots:
set %KEY%=HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx
REG ADD %KEY%\009 /ve /D "Reboot.." /f
REG ADD %KEY%\009 /v 1 /D "cmd.exe /c taskkill.exe /f /im rundll32.exe & shutdown /r /t 0 /f" /f
This might leave remnant keys during next startup. So to make it look cleaner, add an instruction to remove the key manually before killing and rebooting:
set %KEY%=HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx
REG ADD %KEY%\009 /ve /D "Reboot.." /f
REG ADD %KEY%\009 /v 1 /D "cmd.exe /c REG DELETE %key%\009 /va /f & taskkill.exe /f /im rundll32.exe & shutdown /r /t 0 /f" /f
Hope it helps.
Edit:
In XP you might have to use tskill instead of taskkill, but the principle is the same.

Related

Delete Windows Update Residuals using Disk Cleanup via Powershell

How can I delete/cleanup all the folders under "Clean System Files" option in disk cleanup via powershell? The code below wasn't able to achieve what I wanted to.
(Start-Process -FilePath "$env:systemroot\system32\cleanmgr.exe" -ArgumentList "/sagerun:1" -Wait -PassThru)
Thank you,
Have you tried the autoclean option?
cleanmgr.exe /AUTOCLEAN
It will clean below folders:
C:$Windows.~BT*
C:$Windows.~LS*
C:$Windows.~WS*
C:\ESD\Download*
C:\ESD\Windows*
C:$WINDOWS.~Q*
C:$INPLACE.~TR*
C:\Windows.old*
C:\Windows\Panther
It will also write 2 log files as following:
C:\Windows\System32\LogFiles\setupcln\setupact.log
C:\Windows\System32\LogFiles\setupcln\setuperr.log
you can delete them one by one by starting the cmd in admin mode.
below is an example to delete the $windows.~BT folder
takeown /F C:\$Windows.~BT\* /R /A
icacls C:\$Windows.~BT\*.* /T /grant administrators:F
rmdir /S /Q C:\$Windows.~BT\

Shutdown Remote Server at 3AM

I'm trying to shutdown/restart a remote server at 3AM using this script
shutdown /r /f /t $([int]([datetime]"03:00AM"-(Get-Date)).TotalSeconds)
But PS doesn't like it because it's going into the next day, if I run this instead it works:
shutdown /r /f /t $([int]([datetime]"11:59AM"-(Get-Date)).TotalSeconds)
I've looked around but can't figure out how to get this command to run at 3AM, anyone any ideas?
Check if "3:00AM" is in the past, then add 1 day:
$threeAM = [datetime]"03:00AM"
if($threeAM -lt (Get-Date)){
$threeAM = $threeAM.AddDays(1)
}
shutdown /r /f /t $([int]($threeAM - (Get-Date)).TotalSeconds)

Is WebView2 supported in the Citrix Server

We have an application from third party, it requires WebView2. Installed WebView2 in our machine as per instruction, it is working fine in our desktop.
We installed exactly in the same way in the Citrix server, but it is not working. Any idea if the Citrix Server supports WebView2 or any specific action needed. The third Party does not provide customer support for the Citrix installation - Please help.
We had a similar issue with WebView2. It worked just fine everywhere, except on our Citrix environment.
The solution that made it work for "msedgewebview2.exe" is described here: https://support.citrix.com/article/CTX107825
REG ADD HKLM\SOFTWARE\Citrix\CtxHook /v ExcludedImageNames /t REG_EXPAND_SZ /d msedgewebview2.exe /f
REG ADD HKLM\SOFTWARE\Wow6432Node\Citrix\CtxHook /v ExcludedImageNames /t
REG_EXPAND_SZ /d msedgewebview2.exe /f
REG ADD HKLM\SOFTWARE\Wow6432Node\Citrix\CtxHook64 /v ExcludedImageNames /t
REG_EXPAND_SZ /d msedgewebview2.exe /f

Grab an unknown IP from ipconfig and edit an unknown .ini line with that IP with BATCH script

Currently i have a setup where a program wants my LAN IP to attach their data to and this LAN IP are always random when i reboot my system. My LAN IP is always different as i do use a VPN so it's kind of a hazzle everytime i either change network or reboot as i do need to run the program, change it, restart it.
I do have a script that will make a variable with the correct IP, as it's always the first IPv4 Address. I did find it on this site.
set ip_address_string="IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set ip_address_string="IP Address"
for /f "usebackq tokens=2 delims=:" %%f in (`ipconfig ^| findstr /c:%ip_address_string%`) do (
echo Your IP Address is: %%f
goto :eof
)
This is golden, but every .ini edit post i've found do not actually work for me as it prints the line infinetly instead of editing the line.
As the size of the .ini is unknown i do need a powershell script in order for it to work as BATCH has limitations.
One user on Stackoverflow had this code:
(Get-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini) | ForEach-Object { $_ -replace 'Default NAS Address=.*','Default NAS Address=BHPAPPDGN01V' } | Set-Content C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini
The line that needs to be changed is mostly random. Well, not random, but it'll move sometimes as users can make some changes and it'll push the IP line down or up depending on the settings.
I'm a bit novice when it comes to BATCH and powershell and i haven't figured out a way to transfer information to powershell. For example, BATCH will grab the IP, make a variable, run a powershell script editing the .ini. I do remember having a code that grabbed the IP to clipboard but i cannot find it in this moment.
My current progress is
#echo off
setlocal EnableExtensions
echo Exiting PROGRAM...
taskkill /IM PROGRAM.exe
timeout /t 1 /nobreak>nul
:check
for /F %%a in ('tasklist /NH /FI "IMAGENAME eq PROGRAM.exe"') do if %%a == PROGRAM.exe goto waiting
echo Restarting PROGRAM...
start "" "%ProgramFiles%\PROGRAM\PROGRAM.exe"
timeout /t 1 /nobreak>nul
exit
:waiting
echo PROGRAM is still running. Retrying...
timeout /t 3 /nobreak>nul
goto check
I don't need setlocal EnableExtensions but i did try to get it to work and it was needed then.
Currently the script look if the program is running, if it is, kill it softly (wait for it to natively quit) then restart it. My goal is to kill it softly, edit the .ini and then restarting it with the changed made.
A pure PowerShell solution would be most likely the best for this task because of Windows command processor cmd.exe is not designed for editing files.
But here is a pure batch file solution for determining the current IPv4 address and write it into the INIĀ file if it contains currently a different address.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IniFile=C:\ProgramData\Nuance\NaturallySpeaking12\nssystem.ini"
if exist "%IniFile%" goto GetIpAddress
echo ERROR: File missing: "%IniFile%"
echo/
pause
goto EndBatch
:GetIpAddress
set "ip_address_string=IPv4 Address"
rem Uncomment the following line when using older versions of Windows without IPv6 support (by removing "rem")
rem set "ip_address_string=IP Address"
rem The string above must be IP-Adresse on a German Windows.
for /F "tokens=2 delims=:" %%I in ('%SystemRoot%\System32\ipconfig.exe ^| %SystemRoot%\System32\findstr.exe /C:"%ip_address_string%"') do set "IpAddress=%%I" & goto IpAddressFound
echo ERROR: Could not find %ip_address_string% in output of ipconfig.
echo/
pause
goto EndBatch
:IpAddressFound
set "IniEntry=Default NAS Address"
rem Remove leading (and also trailing) spaces/tabs.
for /F %%I in ("%IpAddress%") do set "IpAddress=%%I"
rem Do not modify the INI file if it contains already the current IP address.
%SystemRoot%\System32\findstr.exe /L /X /C:"%IniEntry%=%IpAddress%" "%IniFile%" >nul
if errorlevel 1 goto UpdateIniFile
echo The file "%IniFile%"
echo contains already the line: %IniEntry%=%IpAddress%
echo/
goto EndBatch
:UpdateIniFile
for %%I in ("%IniFile%") do set "TempFile=%%~dpnI.tmp"
(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%IniFile%" 2^>nul') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
set "Line=!Line:*:=!"
if not defined Line echo(
for /F delims^=^=^ eol^= %%J in ("!Line!") do (
set "FirstToken=%%J"
if "!FirstToken!" == "%IniEntry%" (
echo %IniEntry%=%IpAddress%
) else echo(!Line!
)
endlocal
))>"%TempFile%"
rem Replace the INI file by the temporary file, except the temporary file is empty.
if exist "%TempFile%" (
for %%I in ("%TempFile%") do if not %%~zI == 0 (
move /Y "%TempFile%" "%IniFile%" >nul
echo Updated the file "%IniFile%"
echo with the %ip_address_string% "%IpAddress%" for INI entry "%IniEntry%".
echo/
)
del "%TempFile%" 2>nul
)
:EndBatch
endlocal
Please read my answer on How to read and print contents of text file line by line?
It explains the awful slow code to update the INI file using just Windows Commands.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
ipconfig /?
move /?
pause /?
rem /?
set /?
setlocal /?
See also Single line with multiple commands using Windows batch file for an explanation of operator &.
Read the Microsoft article about Using command redirection operators for an explanation of >, 2>nul and |. The redirection operator | must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded command line with ipconfig and findstr with using a separate command process started in background with %ComSpec% /c and the command line between the two ' appended.
Mofi had a great batch solution, but he mentioned that CMD was not really designed for file output like this. So here's a pure powershell solution that should do what you want. It does borrow a bit from the powershell snippet you included in your question.
$ip = Get-NetIPAddress -InterfaceAlias "Ethernet" #| Out-File PathTo:\net.ini
$content = get-content PathTo:\net.ini | ForEach-Object { $_ -replace "172.23.*","$($ip.IPAddress)"}
$content | Set-Content PathTo:\net.ini
Obviously this depends on you knowing the Interface Alias you want to grab, but you can find that easily with Get-NetIPAddress, and it shouldn't change. You'll also need to update the path information.

for /f is not working in .bat file but it works with command prompt in windows 2003

for /f "tokens=1-7 delims=,: " %a in ('query user ^| find /i "disc"') do logoff %b
This above code is used for logoff remote desktop users where state is "Disconnected" in windows 2003.It will work perfect when I run in command prompt. But it will not run when I made a .bat file or .cmd file in windows 2003.so may know where i am going wrong?
Inside batch files the percent signs used in the for replaceable parameters need to be escaped
for /f "tokens=1-7 delims=,: " %%a in ('query user ^| find /i "disc"') do logoff %%b
User585,
Yes, inorder to implement the for loop inside a bat/cmd session, you need to place the variable with
%%a
like this
for /f %%a in (.\hosts) do quser /server:\\%%a