ViciousXUSMC Posted February 26, 2021 Posted February 26, 2021 I may have to give more details and screenshots, but just trying to get a feel for this problem I am having. I am making a piece of software that runs in a lab run as the local admin via Autoit because we do not want to give all the users local admin access for the program to run. I was able to do this using some stuff I found on the forums and it works great. expandcollapse popup#include <Date.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIError.au3> #include <WindowsConstants.au3> #Include <Crypt.au3> Global $sAdminUser = "Administrator" Global $sDomain = @ComputerName Global $iLogOnFlag = 0 Global $sParameters = "" Global $sKey = "REDACTED" Global $sInput = FileRead(@ScriptDir & "\seed.automation") Global $sSeed = _Crypt_DecryptData($sInput, $sKey, $REDACTED) Global $sAdminPassword = BinaryToSTring($sSeed) Global $sSoftware = "C:\Program Files\Hinterland\PC-Titrate V3\PCTitrateV3.exe" ;Elevate with Admin account. If @UserName <> $sAdminUser And Not IsAdmin() Then $sParameters = "" If Not @Compiled Then $sParameters = ' "' & @ScriptFullPath & '"' EndIf If RunAs($sAdminUser, $sDomain, $sAdminPassword, $iLogOnFlag, @AutoItExe & $sParameters) Then Exit Else Exit MsgBox(16 + 262144, "ERROR!", "Unable to run under administrator account.") EndIf EndIf ; Run with Admin Token in Windows Vista and Higher. If @UserName = $sAdminUser And Not IsAdmin() And Not StringRegExp(@OSVersion, "_(XP|200(0|3))") Then $sParameters = "" If Not @Compiled Then $sParameters = '"' & @ScriptFullPath & '"' EndIf If ShellExecute(@AutoITExe, $sParameters, "", "runas") Then Exit Else Exit MsgBox(16+262144, "ERROR!", "Unable to elevate to Admin due to UAC.") EndIf EndIf ; Script for MSI ; Under Vista the Windows API "SetLocalTime" may be rejected due to system security ShellExecute($sSoftware) Except one strange problem, the users can not print reports. It crashes the program, and I found the reason why is that there is no default printer set. Now since the program is running under the local admin context, that is where the default printer needs to be set. Sure enough if I run powershell as another user inside windows manually and use some powershell to set the default printer, it works. And it fixes the printing problem. $wsObject = New-Object -COM WScript.Network $wsObject.SetDefaultPrinter("Nitro PDF Creator (Pro 12)") The strange thing is I can not for the life of me get this scripted. I have tried RunAs() with 0, 1, 2 and 4 . I tried different powershell scripts. I feel like I need RunAs 0 for this to work right and I get an error he system cannot find the file specified. (Exception from HRESULT: 0x80070002) At C:\Automate\Set_Default_Printer.ps1:2 char:1 + $wsObject.SetDefaultPrinter("Nitro PDF Creator (Pro 12)") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], FileNotFoundException + FullyQualifiedErrorId : System.IO.FileNotFoundException This is referring to the printer not being found, even though if will clearly list it if I use something like get-printer It will not give an error under runas context 1 or 2, but the printer is not set and it doesn't fix my issue. The strange thing is if I run powershell as another user manually via the windows interface, run my script and have it work. Then go back and try running my autoit code again it does work! But the fix is already implemented. I tried doing this run as admin, I tried using the same code I am using to run the application itself. i am totally stuck with this one.
TheXman Posted February 26, 2021 Posted February 26, 2021 Where in the process are you actually attempting to set the default printer? Are you doing it in your elevation script right before the execution of $sSoftware, in PCTitrateV3.exe, or somewhere else? CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted February 26, 2021 Author Posted February 26, 2021 8 minutes ago, TheXman said: Where in the process are you actually attempting to set the default printer? Are you doing it in your elevation script right before the execution of $sSoftware, in PCTitrateV3.exe, or somewhere else? I am not setting the default printer for the program, but for Windows but it needs to be see as the default printer for the local admin account, as the program is running as local admin. Not for the current user. So if I run powershell as local admin from right click run as in Windows and then execute a script to set the default printer it works (can be before, or after I run the program, just before we try to print) but when I try to use RunAs() in AutoIT it fails to work no matter what settings I try. I have logged in as the local admin to set a default printer, that did not fix the issue, and even after I fix this issue for a user, it returns at next login. So some system variable obviously does not carry thru based on how I am having to launch this program. And that is that the local non admin user must launch a program as an administrator without admin rights.
TheXman Posted February 26, 2021 Posted February 26, 2021 (edited) I think I know why, but the answer is a long one having to do with the differences between runas() and ShellExecute with the 'runas' verb. Can you try this: Duplicate your elevation script. Replace the line that runs $sSoftware with a line that runs your script that sets the default printer. So basically the same script as before but it sets the default printer. There will be no need for RunAs(), you can just use Run() or ShellExecute(), because you'll already be running under the Administrator context with elevation. If it works that way, then my assumption as to why it is not working is true. If it works and you need an explanation of why, I can point you to some information that will explain it in detail. FYI, you can also set the default printer using the Win32_printer WMI object. If you did it that way, you wouldn't need to shell out to run your PS script. I assume that you do it using PS because your more comfortable using PS than COM? Edited February 26, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted February 26, 2021 Author Posted February 26, 2021 (edited) 48 minutes ago, TheXman said: I think I know why, but the answer is a long one having to do with the differences between runas() and ShellExecute with the 'runas' verb. Can you try this: Duplicate your elevation script. Replace the line that runs $sSoftware with a line that runs your script that sets the default printer. So basically the same script as before but it sets the default printer. There will be no need for RunAs(), you can just use Run() or ShellExecute(), because you'll already be running under the Administrator context with elevation. If it works that way, then my assumption as to why it is not working is true. If it works and you need an explanation of why, I can point you to some information that will explain it in detail. FYI, you can also set the default printer using the Win32_printer WMI object. If you did it that way, you wouldn't need to shell out to run your PS script. I assume that you do it using PS because your more comfortable using PS than COM? I already did try this actually, but I may need to try again and see if I can tweak it to work. (elevation script) and I tried using the WMI object too This gives the same error as otherwise. So it is running, just failing. expandcollapse popup#include <Date.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIError.au3> #include <WindowsConstants.au3> #Include <Crypt.au3> Global $sAdminUser = "Administrator" Global $sDomain = @ComputerName Global $iLogOnFlag = 0 Global $sParameters = "" Global $sKey = "REDACTED" Global $sInput = FileRead(@ScriptDir & "\seed.automation") Global $sSeed = _Crypt_DecryptData($sInput, $sKey, REDACTED) Global $sAdminPassword = BinaryToSTring($sSeed) Global $sSoftware = "powershell.exe -executionpolicy Bypass -File C:\Automate\Set_Default_Printer.ps1" ;Elevate with Admin account. If @UserName <> $sAdminUser And Not IsAdmin() Then $sParameters = "" If Not @Compiled Then $sParameters = ' "' & @ScriptFullPath & '"' EndIf If RunAs($sAdminUser, $sDomain, $sAdminPassword, $iLogOnFlag, @AutoItExe & $sParameters) Then Exit Else Exit MsgBox(16 + 262144, "ERROR!", "Unable to run under administrator account.") EndIf EndIf ; Run with Admin Token in Windows Vista and Higher. If @UserName = $sAdminUser And Not IsAdmin() And Not StringRegExp(@OSVersion, "_(XP|200(0|3))") Then $sParameters = "" If Not @Compiled Then $sParameters = '"' & @ScriptFullPath & '"' EndIf If ShellExecute(@AutoITExe, $sParameters, "", "runas") Then Exit Else Exit MsgBox(16+262144, "ERROR!", "Unable to elevate to Admin due to UAC.") EndIf EndIf ; Script for MSI ; Under Vista the Windows API "SetLocalTime" may be rejected due to system security Run($sSoftware) Even going so far as to just shellexecute("powershell.exe") and then trying to run the commands or script manually does not work, gives the same error. Edited February 26, 2021 by ViciousXUSMC
TheXman Posted February 26, 2021 Posted February 26, 2021 (edited) I just want to make sure that we are on the same page. If you are testing this on Windows 10, by default, the administrator account named Administrator is disabled. If the account named Administrator is disabled, then your script, as currently written, will not work. You can verify whether the status of the Administrator account executing the following command at a cmd prompt and look for the value of "Account active": net user administrator If the account named Administrator is not active, then you will need to use a valid admin account & password in your script or you'll need to make the account active. Edited February 26, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted February 26, 2021 Author Posted February 26, 2021 (edited) The administrator account is Active, you can log into it as a user (and I did that as part of my testing) Part of my validating as I go working on this is to type whoami in the PS or CMD windows to verify I am running as the local administrator under the computer domain. We know it works because the shells are running, and the program is running. If the account was not active/working those things would fail. The process I am trying to get working... I would just assume it cant be done, except.... It works just fine if done like this. Start Button -> Search Powershell -> Right Click Run As Different User -> Type in Local Admin Credentials -> Run any script or commands I want and they work. But no matter how I try to do that via AutoIT it has not worked. The RunAs() is working or Run() / ShellExecute() if used as part of the elevation script. I can run powershell commands and such, but they cant seem to "find" the printer and set it, but again it works when just doing a normal "Run As" from Windows itself. Edited February 26, 2021 by ViciousXUSMC
TheXman Posted February 26, 2021 Posted February 26, 2021 (edited) I see possible issues with the script in your original post. Since discussions of how to get around UAC are off limits, I do not want to say anything directly related to that subject other than your script is not the same as the ones you may have found in your searches on this forum (at least not the ones that worked correctly). I have tested changing the default printer using the basic methodology you are trying to use and it works. Meaning, if you find the issue(s) with your script, you should be golden. Edited February 26, 2021 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted February 26, 2021 Author Posted February 26, 2021 4 minutes ago, TheXman said: I see issues with the script in your original post. Since discussions of how to get around UAC are off limits, I do not want to say anything directly related to that subject other than your script is not the same as the ones you may have found in your searches on this forum (at least not the ones that worked correctly). I have tested changing the default printer using the basic methodology you are trying to use and it works. Meaning, if you find the issue(s) with your script, you should be golden. I cant get this to work even before running my script. A fresh log in and it still will not work.
TheXman Posted February 26, 2021 Posted February 26, 2021 For those looking for your solution, I think you may have written it to the wrong topic. CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted March 1, 2021 Author Posted March 1, 2021 Yes I had it working, we did more testing and it's still not working. WHEN it is working the powershell will exit 0, running as RunAs 0. When it is not working it will exit 2. what it appeared was happening is RunAs 1, which always exits 0, if run first would then have the next run of RunAs 0 work. I repeated it a couple of times I thought, but at the end of the day had a user I could not get it working. I wonder if maybe one of my test users was a local admin and the other was not, and I am still stuck with this one. It still works 100% of the time every time when done manually, but of course that requires me to type in the credentials for UAC and thus gives me administrative elevation when just RunAs() does not. So I need to find a way to get this working in my elevation script I suppose.
xcaliber13 Posted March 1, 2021 Posted March 1, 2021 Have you tried the set default printer function? _PrintMgr_SetDefaultPrinter("Name of your Printer") Func _PrintMgr_SetDefaultPrinter($sPrinterName) Local $iRet = 1 Local $oWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") If NOT IsObj($oWMIService) Then Return SetError(1, 0, 0) Local $oPrinters = $oWMIService.ExecQuery ("Select * from Win32_Printer where DeviceID = '" & $sPrinterName & "'") If NOT IsObj($oPrinters) Then Return SetError(1, 0, 0) For $oPrinter in $oPrinters $iRet = $oPrinter.SetDefaultPrinter() Next Return ($iRet = 0 ? 1 : SetError($iRet, 0, 0)) EndFunc ; ==> _PrintMgr_SetDefaultPrinter
ViciousXUSMC Posted March 3, 2021 Author Posted March 3, 2021 On 3/1/2021 at 8:52 AM, xcaliber13 said: Have you tried the set default printer function? _PrintMgr_SetDefaultPrinter("Name of your Printer") Func _PrintMgr_SetDefaultPrinter($sPrinterName) Local $iRet = 1 Local $oWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") If NOT IsObj($oWMIService) Then Return SetError(1, 0, 0) Local $oPrinters = $oWMIService.ExecQuery ("Select * from Win32_Printer where DeviceID = '" & $sPrinterName & "'") If NOT IsObj($oPrinters) Then Return SetError(1, 0, 0) For $oPrinter in $oPrinters $iRet = $oPrinter.SetDefaultPrinter() Next Return ($iRet = 0 ? 1 : SetError($iRet, 0, 0)) EndFunc ; ==> _PrintMgr_SetDefaultPrinter Not yet, but sure will
ViciousXUSMC Posted March 5, 2021 Author Posted March 5, 2021 No luck in that, added it to the elevation script thought it might work. Its essentially the same code I was using in my powershell script but I liked that I could run it natively.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now