Running multiple apps as Admin - c#

I've need to add a function to my C# WPF application to fix up certain registry entries.
This would be done by calling regsvr32.exe /s mylib.dll. Now, this should be easy to do from what I see using the runas verb with a new Process object. (My dll does require admin rights due to some registry keys it writes to.)
But the problem is there are multiple DLLs, thus multiple invocations of regsvr32.exe, and it is not possible to put all the registrations into a single .dll. But were I to just runas multiple times, the user would get as many UAC dialogs as I start it... and I don't want that.
I want just a single dialog, and I really really want to avoid having a mystery extra fixer.exe file to have to do the launching instead. Now, I only know Windows Security stuff on a really basic level, but shouldn't it be possible to get an 'admin' token somehow (which gets me the UAC dialog) and use that to launch the different processes?

You can just use command line arguments, and shell to your own .exe running that process as an admin. When your application loads, check for those command line arguments...If they are there, register all of your dlls, then exit.
Or, you could write a batch file that registers all of the dlls, and shell to that with admin rights.

The issue here is security. You have three options:
Create a service account and run the application with service account privileges.
Prep the target machines that the application will run on with some sort of install package.
Use powershell to invoke regsvr32.exe with admin rights ->
function Run-Elevated ($scriptblock)
{
# TODO: make -NoExit a parameter
# TODO: just open PS (no -Command parameter) if $sb -eq ''
$sh = new-object -com 'Shell.Application'
$sh.ShellExecute('powershell', "-NoExit -Command $sb", '', 'runas')
}
I would opt for option 2, as registering dll's are more than an installation step. The registering of the dll crosses the boundary of the account privileges needed to run the main application. If your app is running on a domain environment an MSI could be rolled out to prep each machine?

If you want only one single UAC prompt, there is already an answer at Stackoverflow, look here.
This script elevates itself once, and you can execute a sequence of commands which all need elevated rights, so you don't get multiple UAC prompts anymore.
In your case, this means you can just append the invokations of
regsvr32.exe /s mylib1.dll
regsvr32.exe /s mylib2.dll
regsvr32.exe /s mylib3.dll
at the end of the script mentioned above, i.e.
:::::::::::::::::::::::::::::::::::::::::
:: Automatically check & get admin rights
:::::::::::::::::::::::::::::::::::::::::
#echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (shift & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
"%temp%\OEgetPrivileges.vbs"
exit /B
:gotPrivileges
::::::::::::::::::::::::::::
:START
::::::::::::::::::::::::::::
setlocal & pushd .
REM The following code will cause Windows UAC to prompt only once
regsvr32.exe /s mylib1.dll
regsvr32.exe /s mylib2.dll
regsvr32.exe /s mylib3.dll
and the UAC dialog will only appear once.

Related

macos + C# : how can I start process with sudo prompt

I have an application built in C# .dotnet 6 on macos.
I want the application to be able to seamlessly update itself.
It's downloads the latest pkg and my problem is how I run it.
I want to start this process using "sudo installer -pkg /tmp/mypackage.pkg -target /" but sudo ask for password on the standard input.
How can I start a process with escalated privileges where the user permissions are asked first through something like:
You can use AppleScript to create a graphical authentication prompt:
#!/bin/sh
osascript -e "do shell script \"$*\" with administrator privileges"
Other methods: Is there any graphical "sudo" for Mac OS X?
You could try the option -S of sudo for accepting the password from standard input. After use echo password and | to pass the password to the command:
echo myPassword | sudo -S installer -pkg /tmp/mypackage.pkg -target

how to have a windows service self update?

All the solutions I can find on this topic are very old and none of them appear to answer my question...
I am trying to create a windows service that can self update (or auto update by some external trigger). In the past, I had created a windows service that was installed with InstallShield and we were able to update auto update the service in a hacky way by making the service write a batch script to the local machine and then run the batch script, which would stop the service, overwrite the service executable and other files with the new ones, and restart the service. This surprisingly worked.
However, I have updated the service to use InstallUtil.exe and this auto update script no longer works... I assume it's something to do with the way InstallShield handles the service install vs how InstallUtil does it... but I can only make guesses as I don't fully understand what each is doing to the registry.
Since I can't just overwrite the files and restart the service with the InstallUtil method, I thought I'd write a batch script that runs sc.exe to stop the service, uninstall it entirely, write the new files, install the new service files, and then start it... unfortunately, I can't seem to get sc.exe to run from a windows service automatically because it requires admin permissions... I tried to force it to self-elevate to admin using this snippet, but it doesn't appear to work as a service (it works fine if I run it from command line not as a service)
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
Does anyone know how I can cause a windows service to self update? I can look into updating to a .NET Core Worker service if there is some method of self update in .NET Core that I'm unaware of... Any ideas are much appreciated... it really shouldn't be this hard to accomplish...
For reference, here is the batch script I am currently using (ignore odd variables and such as I am dynamically replacing some of them, it works great when launched manually, just doesn't work when the service tries to run it):
#echo off
setlocal enableextensions enabledelayedexpansion
::make sure to run whole script as admin (this restarts scripts as admin if not already in admin mode)
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
pushd %networkDirectory%
::stop running service
for /F "tokens=3 delims=: " %%H in ('sc query %serviceName% ^| findstr " STATE"') do (
if /I "%%H" NEQ "STOPPED" (
net stop %serviceName%
if errorlevel 1 goto :stop
)
::delete existing service after stopping
sc delete %serviceName%
)
:: install updated service files
set "releaseDir=%networkDirectory%\Release"
set "programFilesCopyDir=%ProgramFiles%\{_companyDirectory}\%serviceName%\Release"
:: copy service Release dir to local system program files
xcopy "%releaseDir%" "%programFilesCopyDir%" /S /Y /Q
::execute the install
pushd "%programFilesCopyDir%"
CALL %serviceName%.exe --install
::start service
sc start %serviceName%
For anyone else trying to accomplish this that stumbles on this... I ended up finding a solution. I use the same script posted in my question above, but I wrote code to set up a scheduled task with Windows Task Scheduler. The scheduled task runs the above script as a one time scheduled task. This works like a charm.
I used this NuGet package to write the Task Scheduler code I needed:
https://www.nuget.org/packages/TaskScheduler/2.8.20?_src=template

Suppress UAC Account Settings window while installing SQL Server 2008 Service pack silently

I have two account's on my PC, an admin account an user account. User account has admin privileges to install new programs. I usually work with my user account. When I want to install a SQL Server service pack 3 for SOL Server 2008, the UAC window prompts me to click yes or no to continue installation.
I don't want that to happen. I need no interruption during my installation.
How can I suppress that UAC message box ?
I am calling a .BAT file from my C# program. This is the command line:
start /WAIT C:\Temp\SQLSP3.exe /quiet
/IAcceptSQLServerLicenseTerms /Action=Patch /AllInstances
Following is the UAC prompt. Please help me in supressing this.
This is the C# code to elevate the BAT file execution with Admin Credentials.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = windrive + #"temp\SQLSP3.BAT";
p.StartInfo.Arguments = DateTime.Now.ToShortDateString().ToString().Replace('/', '-') + ".db";
p.StartInfo.UserName = "Admin";
SecureString adminpassword = new SecureString();
adminpassword = ConvertToSecureString(Password);
p.StartInfo.Password = adminpassword;
try
{
p.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.InnerException);
Console.ReadLine();
}
This following command has disabled the UAC Prompt before installation of SQL SP3 pack.
C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f
C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f
I posted a somewhat granular (but ugly) solution here:
http://stackoverflow.com/questions/5344021/bypass-uac-in-vbscript/34445992#34445992
Basically you need to have a task scheduler point to the install '.exe' file. The install '.exe' file would need to always have the same name and be in the same directory. My implementation fires the event from vbscript but there is no reason why you can't do it from any '.net' language. You would need to change the 'WSH' in the taskscheduler event filter to the appropriate string if you don't stick with firing the event from vbscript.
It only works if you can kick off an application from the task scheduler. I have it running on two Windows 7 laptops. It is an administrative solution. You need administrator privilege to implement it. I use it for powershell and for my UPS power backup application. I suspect I'll find other uses.

Web deployment task failed (This access control list is not in canonical form and therefore cannot be modified)

Publishing ASP.NET MVC 4 application to IIS 8 on my machine giving the following error :
This access control list is not in canonical form and therefore cannot be modified.
I am under Windows 10 and using VS 2013 Ultimate.
I installed web deploy 3.5 from web platform installer 5, and I made sure that the services are working
Solution 1
I was able to solve this problem in the following way
Go to IIS
Right click on the website that you are publishing to and select Edit Permissions
Click the Security tab.
Click on Edit button
A Message box will appear which tell that the Permission was not correctly ordered.
Click Reorder on that message box.
Solution 2
Open the Command prompt (CMD) and execute the following two statements
icacls.exe C:\inetpub\wwwroot /verify /T /C /L /Q
icacls.exe C:\inetpub\wwwroot /reset /T /C /L /Q
note : Maybe you will want to open the CMD with Administrator privilege (Maybe I am not sure)
Cheers
You can run the following command to fix it
command prompt
icacls.exe C:\inetpub\wwwroot\<VIRTUAL DIRECTORY> /verify /T /C /L /Q
// If any entries are reported as being not in canonical order then run:
icacls.exe C:\inetpub\wwwroot\<VIRTUAL DIRECTORY> /reset /T /C /L /Q
Source
powershell
$path = C:\inetpub\wwwroot\<VIRTUAL DIRECTORY>
$acl = Get-Acl $path
Set-Acl $path $acl
Source
You can prevent this problem by modifying your Visual Studio package generation parameters: In the PropertyGroup section of your pubxml file, add
<IncludeSetACLProviderOnDestination>False</IncludeSetACLProviderOnDestination>

Windows Task Scheduler Installer

I have a little .exe written in c# .net that I want to run on the server every 24 hours. So naturally I would just use the Windows Task Schedular rather then doing the math myself. I have created the program, but I would like to create an installer that just set everything up. Is there a way to do this with like the Visual Studio set-up projects? If not is there like a powershell / batch script that could be used to run after installation?
Bottom Line: Automate the creation of the task.
You can use a powershell script or batch file to execute schtasks which is a command line interface to the task scheduler.
Then you simply need to run the script in order to setup the scheduled task.
There is also a managed wrapper that allows you to create schedules tasks in C#, if you would rather go that way.
I know this is an old question, but I figure this may help someone else:
You can use the following to run in cmd.exe
FOR /F %1 IN ("path to text file containing list of servers") do psexec.exe \\%1 -u
"username to execute schtasks under" -p "password" schtasks /Create /S %1
/RU "username that will run the task" /RP "password" /XML "xml file of
the task to install" /TN "name of the task"
This will loop through the list of servers in a text file (1 server per line) and use psexec to call schtasks on each server and install your task.

Categories

Resources