Fixing Windows 10 Broken Apps

email me

If you’re Windows 10 apps aren’t opening, or you’re receiving errors when you click shortcuts on the Start Menu, try this:

Open the Task manager. Click File > Run new task.

In the task dialog box, make sure you check Create this task with administrative privileges.

Type CMD

Type the following 4 commands in the console:

dism /online /cleanup-image /restorehealth

sfc /scannow

powershell

Get-AppXPackage -AllUsers |Where-Object {$_.InstallLocation -like “*SystemApps*”} | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml”}

 

Notes

If you have problems, log in as administrator, not using a Microsoft online account, and try again.

 

Using a different source WIM

Dism /Online /Cleanup-Image /RestoreHealth /Source:wim:D:\sources\install.wim:1 /limitaccess

 

Repair Windows Store

cmd > wsreset.exe

PowerShell -ExecutionPolicy Unrestricted -Command “& {$manifest = (Get-AppxPackage *WindowsStore*).InstallLocation + ‘\AppxManifest.xml’ ; Add-AppxPackage -DisableDevelopmentMode -Register $manifest}”

 

tags: repair apps, restore apps, fix broken apps

Adobe Flash: Microsoft Security Bulletin MS17-023 – Critical

email me

https://technet.microsoft.com/en-us/library/security/MS17-023

Executive Summary

This security update resolves vulnerabilities in Adobe Flash Player when installed on all supported editions of Windows 8.1, Windows Server 2012, Windows Server 2012 R2, Windows RT 8.1, Windows 10, and Windows Server 2016.

This security update is rated Critical. The update addresses the vulnerabilities in Adobe Flash Player by updating the affected Adobe Flash libraries contained within Internet Explorer 10, Internet Explorer 11, and Microsoft Edge.

For more information about this update, see Microsoft Knowledge Base Article 4014329.

Vulnerability Information

This security update addresses the following vulnerabilities, which are described in Adobe Security Bulletin APSB17-07:

CVE-2017-2997, CVE-2017-2998, CVE-2017-2999, CVE-2017-3000, CVE-2017-3001, CVE-2017-3002, CVE-2017-3003.

Juniper Pulse Client Removal

email me

reg delete “HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers” /f
reg delete “HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes” /f
reg delete “HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols” /f

  1. Uninstall Juniper or Junos software from Control Panel > Programs and Features; remove all instances of the app.
  2. Delete Juniper and / or Pulse folders from
    C:\Program Files x86\
    C:\Program Files x86\CommonFiles\
    C:\Users\Public
    C:\Users\%username%\AppData\Roaming\
    C:\Users\%username%\AppData\Local\
    C:\ProgramData\
  3. Delete JuniperSetupControl from Start >Control Panel > Internet Options > General > Settings > View Objects
  4. Remove the Juniper Networks Virtual Adapter from Device Manager, click View on top > Select Show Hidden Devices > Go to the Network Adapter and remove Juniper Networks Virtual Adapter
  5. Delete the Juniper / Pulse keys  from the registry:
    HKEY_CURRENT_USER\Software\Juniper Networks
    HKEY_CURRENT_USER\Software\Pulse
    HKEY_LOCAL_MACHINE\Software\Juniper Networks
    HKEY_LOCAL_MACHINE\Software\Pulse
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\dsNcApt
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\dsNcService
  6. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion the value ‘DevicePath’ should point to ‘%SystemRoot%\inf’.
  7. Open a command line “as Administrator”, run “pnputil -e > pnplist.txt”, find everything in there that has the name JUNIPER or PULSE in it, then run “pnputil -d oemXX.inf” for each entry, where “XX” is the actual number of the entry.
  8. Restart the machine.
  9. Download and install Juniper Setup Client (I get these MSIs directly from the vendor).
  10. Manually install NCINST64.EXE and check to ensure that it is running on the PC’s SERVICES.  If it is not running, it likely will not start, and if you try to VPN in you will likely see error 23787. 14. Manually install the Pulse Installer Service.
  11. Launch Pulse, set up profile, and try logging in.

PowerShell – Move/Disable Inactive Computers in AD

email me

This is a PowerShell script I wrote to move/disable inactive computer accounts.

Download and install Quest ActiveRoles Management Shell:
http://eddiejackson.net/apps/Quest_ActiveRolesManagementShellforActiveDirectoryx64_151.zip

# SET INACTIVE DAYS
$SetInactive = 120

# SEARCH HERE
$SourceOU = "ou=SEARCHHERE,dc=DOMAIN,dc=com"

# MOVE HERE
$TargetOU = "ou=MOVEHERE,dc=DOMAIN,dc=com"

# REPORT MODE
# Set to True to only show list of computers
# True or False
$RunReport = "True"

# DISABLE COMPUTER ACCOUNT
# Set to True to also disable the computer account
# True or False
$DisableAccount = "False"



#-----------------------------------------------
Add-PSSnapin Quest.ActiveRoles.ADManagement
Clear-Host

If ($RunReport -eq "True") {

    #REPORT MODE
    Write-Host "Report Mode..."
    Write-Host ""
    Get-QADComputer -InactiveFor $SetInactive -SizeLimit 0 -SearchRoot $SourceOU -IncludedProperties ParentContainerDN | foreach {
    $_.ComputerName
}

} else {

    #KILL MODE
    Write-Host "Kill Mode..."
    Write-Host ""

    $objectDescription = "$(Get-TimeStamp) Account moved due to inactivity - SysAdmin"

    Get-QADComputer -InactiveFor $SetInactive -SizeLimit 0 -SearchRoot $SourceOU -IncludedProperties ParentContainerDN | foreach {

    $computer = $_.ComputerName
    $SourceOU = $_.DN

    Set-QADComputer $computer -Description $objectDescription

    If ($DisableAccount -eq "True") {Disable-QADComputer $computer}
        #Enable-QADComputer $computer

    Move-QADObject $computer -NewParentContainer $TargetOU
    "$(Get-TimeStamp) $computer" | Out-File -FilePath $ENV:UserProfile\Desktop\_ADLog.txt -Append
    Write-Host ""

    }
}

function Get-TimeStamp {
    $SetTimestamp = "[" + (Get-Date).ToShortDateString() + " " + ((Get-Date).ToLongTimeString()) + "]"
    Return $SetTimestamp
}

Windows Build Numbers

email me

Operating System Version / Build / Date
Windows 95 OEM Service Release 1 (95A) 4.00.950 A
Windows 95 OEM Service Release 2 (95B) 4.00.1111 B
Windows 95 OEM Service Release 2.1 4.03.1212-1214 B
Windows 95 OEM Service Release 2.5 C 4.03.1214 C
Windows 98 4.10.1998
Windows 98 Second Edition (SE) 4.10.2222 A
Windows Millennium Beta 4.90.2476
Windows Millennium 4.90.3000
Windows NT 3.1 3.10.528.1 (9/11/1993)
Windows NT 3.5 3.50.807 (9/21/1994)
Windows NT 3.51 3.51.1057 (5/30/1995)
Windows NT 4.00 4.00.1381 (8/24/1996)
Windows NT 5.00 (Beta 2) 5.00.1515
Windows 2000 (Beta 3) 5.00.2031
Windows 2000 (Beta 3 RC2) 5.00.2128
Windows 2000 (Beta 3) 5.00.2183
Windows 2000 5.00.2195 (2/17/2000)
Whistler Server Preview 2250
Whistler Server alpha 2257
Whistler Server interim release 2267
Whistler Server interim release 2410
Windows XP (RC 1) 5.1.2505
Windows XP 5.1.2600 (10/25/2001)
Windows XP, Service Pack 1 5.1.2600.1106 (9/9/2002)
Windows XP, Service Pack 2 5.1.2600.2180 (8/25/2004)
Windows XP, Service Pack 3 5.1.2600.5512 (4/21/2008)
Windows .NET Server interim 5.2.3541
Windows .NET Server Beta 3 5.2.3590
Windows .NET Server Release Candidate 1 (RC1) 5.2.3660
Windows .NET Server 2003 RC2 5.2.3718
Windows Server 2003 (Beta?) 5.2.3763
Windows Server 2003 5.2.3790 (4/24/2003)
Windows Server 2003, Service Pack 1 5.2.3790.1180
Windows Server 2003 5.2.3790.1218
Windows Home Server 5.2.3790 (6/16/2007)
Windows Longhorn 6.0.5048
Windows Vista, Beta 1 6.0.5112 (7/20/2005)
Windows Vista, Community Technology Preview (CTP) 6.0.5219 (8/30/2005)
Windows Vista, TAP Preview 6.0.5259 (11/17/2005)
Windows Vista, CTP (December) 6.0.5270 (12/14/2005)
Windows Vista, CTP (February) 6.0.5308 (2/17/2006)
Windows Vista, CTP (Refresh) 6.0.5342 (3/21/2006)
Windows Vista, April EWD 6.0.5365 (4/19/2006)
Windows Vista, Beta 2 Preview 6.0.5381 (5/1/2006)
Windows Vista, Beta 2 6.0.5384 (5/18/2006)
Windows Vista, Pre-RC1 6.0.5456 (6/20/2006)
Windows Vista, Pre-RC1, Build 5472 6.0.5472 (7/13/2006)
Windows Vista, Pre-RC1, Build 5536 6.0.5536 (8/21/2006)
Windows Vista, RC1 6.0.5600.16384 (8/29/2006)
Windows Vista, Pre-RC2 6.0.5700 (8/10/2006)
Windows Vista, Pre-RC2, Build 5728 6.0.5728 (9/17/2006)
Windows Vista, RC2 6.0.5744.16384 (10/3/2006)
Windows Vista, Pre-RTM, Build 5808 6.0.5808 (12.10.2006)
Windows Vista, Pre-RTM, Build 5824 6.0.5824 (10/17/2006)
Windows Vista, Pre-RTM, Build 5840 6.0.5840 (10/18/2006)
Windows Vista, RTM (Release to Manufacturing) 6.0.6000.16386 (11/1/2006)
Windows Vista 6.0.6000 (11/8/2006)
Windows Vista, Service Pack 2 6.0.6002 (2/04/2008)
Windows Server 2008 6.0.6001 (2/27/2008)
Windows 7, RTM (Release to Manufacturing) 6.1.7600.16385 (10/22/2009)
Windows 7 6.1.7600 (10/22/2009)
Windows 7, Service Pack 1 6.1.7601
Windows Server 2008 R2, RTM (Release to Manufacturing) 6.1.7600.16385 (10/22/2009)
Windows Server 2008 R2, SP1 6.1.7601
Windows Home Server 2011 6.1.8400 (4/5/2011)
Windows Server 2012 6.2.9200 (9/04/2012)
Windows 8 6.2.9200 (10/26/2012)
Windows Phone 8 6.2.10211 (10/29/2012)
Windows Server 2012 R2 6.3.9200 (10/18/2013)
Windows 8.1 6.3.9200 (10/17/2013)
Windows 8.1, Update 1 6.3.9600 (4//8/2014)
Windows 10 10.0.10240 (7/29/2015)
Windows 10 (1511) 10.0.10586 (11/10/2015)
Windows 10 (1607) 10.0.14393 (2/8/2016)
Windows 10 (1703) 10.0.15063 (04/11/2017)
Windows 10 (1709) 10.0.16299 (10/17/2017)
Windows 10 (1803) 10.0.17134 (5/8/2018)
Windows 10 (1809) 10.0.17763 (10/2/2018)
Windows 10 (1903) 10.0.18362 (05/21/2019)
Windows 10 (1909) 10.0.18363 (11/12/2019)
Windows 10 (2004) 10.0.19041 (5/27/2020)
Windows 10 (20H2) 10.0.19042 (10/20/2020)
Windows 10 (21H1) 10.0.19043 (05/18/2021)
Windows 10 (21H2) 10.0.19044 (11/16/2021)
Windows 10 (22H2) 10.0.19045 (10/18/2022)

Visual Studio – TextHighlighterExtension2015

email me

This Visual Studio extension offers syntax highlighting for the following text formats:

.bat (also offer limited intellisense)
.cmd
.ini
.Log4j.properties file
.sh Bash file (alpha)
.txt
.log
.json is now supported by Visual Studio 2015!
(see bottom for extension)

.ps1
(also see bottom for PoshTools)

 

The extension comes with default colors set for black and white background.

To change colors, check here:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r5vacxma.cek\COLORS_DEFINITION_DARK.json

C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r5vacxma.cek\COLORS_DEFINITION_LIGHT.json

To update keywords, check here:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r5vacxma.cek\KEYWORDS.json

To add intellisense to batch files, check here:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\r5vacxma.cek\Intellisense.json

 

Snapshot of the highlighting in Visual Studio (I love it!)

* I did have to run this as administrator for it to work, but I don’t care…still love it.

 

   

Visual Studio – Command Task Runner

email me

This Visual Studio extension adds support for command line batch files in Visual Studio 2015’s Task Runner Explorer.

Supports .exe, .cmd, .bat, .ps1 and .psm1 files.

 

Add commands

The easiest way to add a batch file to Task Runner Explorer is to right-click it in Solution Explorer and select Add to Task Runner

You can right-click supported batch files in either solution folders or from within a any project.

Doing so will create a commands.json file. If you right-clicked a batch file in a solution folder, then the commands.json file will be placed in the solution folder. If the batch file is in a project you will be prompted to select to either put it in the project or solution folder.

If a commands.json file already exist, the new batch file will be added.

 

Execute scripts

When scripts are specified, the Task Runner Explorer will show those scripts.

Each script can be executed by double-clicking the task.

 

commands.json locations

The Task Runner Explorer supports multiple task runners in the same solution. For instance, you can have commands specified for the solution and additional ones for each project in that solution.

Task Runner Explorer will try to find a commands.json file in any parent folder to either the individual projects or the solution until it hits the root of the drive.

 

Commands

Inside commands.json it is possible to add custom scripts inside the “scripts” element.

{ “commands”: { “Build”: { “FileName”: “cmd.exe”, “WorkingDirectory”: “.”, “Arguments”: “/c build\build.cmd” } }}

 

PowerShell – Change Registry Key Permissions

email me

$regPath = "HKLM:\SOFTWARE\JavaSoft"

Try  {
        Get-ItemProperty $regPath -ErrorAction Stop        
        $regACL = Get-ACL $regPath
        $regRule= New-Object System.Security.AccessControl.RegistryAccessRule("Everyone","ReadPermissions","Allow")
        #("Everyone","FullControl","Allow")
        $regACL.SetAccessRule($regRule)
        Set-Acl $regPath $regACL
        Write-Host "Success!"
      }

Catch {
            
         Write-Host "Failed!"
      }

Notes

$x = $regACL.AccessRightType.IsPublic
if ($x -eq "True" ) {write-host "Success"}

$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\JavaSoft",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$regACL = $regKey.GetAccessControl()
$regRule = New-Object System.Security.AccessControl.RegistryAccessRule ("User","FullControl","Allow")
$regACL.SetAccessRule($regRule)
$regKey.SetAccessControl($regACL)

Script Engine Example in Batch – v2

email me

This is version two of this: I wrote this to install a ‘prepared’ package to a single computer, or to a list of computers. It’s low tech to get around the numerous problems associated with remote installation using PowerShell, VBScript, or desktop management applications.

cls
@Echo off
Title Remote Engine by Eddie Jackson
color 0a
Setlocal EnableDelayedExpansion


:: SET COMMAND
set fileName=Sequence.cmd
set fileOpt=
set workDir=c:\windows\system32
set hidden=No

Set PCList=computers.txt
:: or
Set PC=



:: INTERNAL 
:BEGIN
c:
cd "%~dp0"
set Script=False
for %%i in (%fileName%) do set cmdExt=%%~xi
set Interact=-i
if [%cmdExt%]==[.cmd] set Script=True
if [%cmdExt%]==[.CMD] set Script=True
if [%cmdExt%]==[.bat] set Script=True
if [%cmdExt%]==[.BAT] set Script=True
if [%cmdExt%]==[.vbs] goto VBS
if [%cmdExt%]==[.VBS] goto VBS
if [%hidden%]==[Yes] set Interact=

set cmdPath=%workDir%\%fileName%

:: CREATES DATE AND TIME TIMESTAMP
:: sets a static timestamp
for /F "tokens=2-4 delims=/- " %%p in ('date/T') do set mdate=%%r%%p%%q
for /F "tokens=1-2 delims=:- " %%p in ('time/T') do set mtime=%%p%%q
Set Report=logs\%mdate%_%mtime%_%report%.txt
md logs>nul
cls
if not [%PC%]==[] goto SINGLE
goto MULTI


:: PROGRAM ROUTINE
:MULTI
Echo.
Echo [Entering multi computer mode]
Echo.

if not exist "%PCList%" (
Echo Computers text file not found^^!
echo.
pause
exit
)

Set cmdRem=PAExec.exe \\%%a -s %Interact% -w %workDir% "%cmdPath%" %fileOpt%

for /f "tokens=* delims= " %%a in (%PCList%) do (

echo Contacting %%a...
ping %%a -w 250 | find "Reply">nul
if errorlevel 1 (echo %%a,Offline >>"%Report%"
) else ( 
echo %%a,Online >>"%Report%"

if %Script%==True copy /y %fileName% \\%%a\c$\windows\SysWOW64\%fileName%>nul

:: LAUNCH REMOTE COMMAND
echo Launching %cmdPath% on %%a...
%cmdRem%>nul && Echo %%a,Success >>"%Report%" || Echo %%a,Failed >>"%Report%"
echo.
)
)
goto END


:SINGLE
Echo.
Echo [Entering single computer mode]
Echo.

Set cmdRem=PAExec.exe \\%PC% -s %Interact% -w %workDir% "%cmdPath%" %fileOpt%

echo Contacting %PC%...
echo.
ping %PC% -w 250 | find "Reply">nul
if errorlevel 1 (echo %PC% is Offline^^!
) else ( 
echo %PC% is Online^^!
echo.

if %Script%==True copy /y %fileName% \\%PC%\c$\windows\SysWOW64\%fileName%>nul

:: LAUNCH REMOTE COMMAND
echo Launching %cmdPath% on %PC%...
echo.
%cmdRem%>nul && Echo Success^^! || Echo Failed^^!
echo.
goto END
)

:: EXIT
:END
Echo.
Echo Done^^!
pause
endlocal
exit /b 0


:VBS
Echo VBScripts are NOT SUPPORTED^^!
echo.
pause
exit

 

 

Notes

Run GPUpdate on List of Servers

FOR /F “tokens=*” %%A IN (C:\script\servers.txt) DO WMIC /Node:%%A Process call create “cmd.exe /c gpupdate”

$List = ‘server1′,’server2′,’server3′,’server4’
foreach ($server in $List) {psexec \\$server gpupdate}


Move to current directory

c:
cd “%~dp0”


Execute EXEs dynamically

@ECHO OFF
FOR /f “tokens=*” %%A IN (‘dir /b *.exe’) DO (
ECHO Filename: “%%A”
:: “%%A” /SILENTINSTALLOPTIONS
:: or
:: start “” “%%A”
)
pause

 

tags: Batch current directory, dir /b output, script engine, MrNetTek

LANDesk Client Elevated Repair – Proof of Concept

email me

I created a LANDesk Repair tool which can be used by any user to repair, reinstall, and fix issues related to the LANDesk client. The magic part of this is that it uses a public URL to download the LANDesk setup file, and then launches in an elevated mode using Microsoft’s SecureSubstring (the secure part was written in C#).

The advantage of having something like this, versus a package compiled with the LD setup file (172MB), is that the package is much smaller (less than a meg) and—if and when you change the LD setup—there is no need to recompile the package with the updated source file. Just drop the new source file at the URL, and anyone using the Repair Tool will automatically get the updated source file; this works for on site and off site users.

Originally, I just wanted to create a proof-of-concept prototype, but it worked so well, it was implemented.

Screenshot of my HTA

 

' ---------------------------------------------------------------' 
' Author:   Eddie Jackson
' File:     LANDesk_Repair.exe
' Purpose:  To repair or reinstall LANDesk
' Version:  1.0
' Date:     4/11/2017
'
' Usage:    Installed to C:\AFolderOfYourChoice
'           Accessed from Start Menu
' Notes
' Exit codes are 0 success, 1 no source file, 2 failed download
' ---------------------------------------------------------------' 


Option Explicit

'global declarations
Dim varHTTP, varBinaryString, setupFile, setupURL, uninstallFile, ComputerName, CurDir
Dim objShell, oldLANDesk, newLANDesk, msgFile, fso, objWMIService, cmd, colProcesses, Elevate



'Sequencing...
InitializeVariables()
CheckURL()
Download(setupFile)
Verify(setupFile)
Uninstall(oldLANDesk)
Install(newLANDesk)
ExitSequence(0)




sub InitializeVariables()
	on error resume next	
	
	'computer name
	ComputerName = "."

	CurDir = "C:\AFolderOfYourChoice"
	
	'message file
	msgFile = CurDir & "\ldmsg.dat"

	Set objShell = CreateObject("WScript.Shell")
	Set fso = CreateObject("Scripting.FileSystemObject")	
 
	Set varHTTP = CreateObject("Microsoft.XMLHTTP")
	Set varBinaryString = CreateObject("Adodb.Stream")
	
	setupFile = "Client_From_ldlogon_AdvanceAgent_Folder.exe"
	uninstallFile = "UninstallWinClient_From_LANDesk.exe"
	
        'tool I created to do elevation
        Elevate = CurDir & "\Elevate.exe -app" & " "
        'reference: http://eddiejackson.net/wp/?p=13815
	
	oldLANDesk = Elevate & chr(34) & CurDir & "\" & uninstallFile & chr(34) & " " & chr(34) & "/NOREBOOT /FORCECLEAN" & chr(34)
	newLANDesk = Elevate & chr(34) & CurDir & "\" & setupFile & chr(34)
	setupURL = "http://YourGateway_CSA_or_DMZ/" & setupFile

	varHTTP.Open "GET", setupURL, False
	varHTTP.Send
end sub


sub CheckURL()
    on error resume next
	'launch splash	
	Msg("Searching for download file...")	
	Splash()
	
	Select Case Cint(varHTTP.status)		
		Case 200, 202, 302			
			Msg("Found LANDesk download file!")			
			Exit Sub
		Case Else			
			Msg("LANDesk setup could not be found!")			
			ExitSequence(1)
	End Select
end sub


sub Download(dFile)
		on error resume next
		Msg("Downloading LANDesk file...")	
		With varBinaryString
			.Type = 1 'my type has been set to binary
			.Open
			.Write varHTTP.responseBody
			.SaveToFile ".\" & dFile, 2 'if exist, overwrite
		End With
		varBinaryString.close		
		Msg("LANDesk setup has been downloaded...")		
end sub


sub Uninstall(uCommand)
		on error resume next
		Msg("Removing old LANDesk setup...")	
		
		objShell.Run uCommand,0,True
		Wait(20)
		
		Monitor(uninstallFile)	
		Msg("LANDesk has been removed...")
end sub


sub Verify(vDownload)
	on error resume next
	Msg("Verifying file integrity...")
	
	If (fso.FileExists(CurDir & "\" & vDownload)) Then
		Msg("Download was successful!")
	Else
		Msg("Download failed!")
		ExitSequence(2)
	End If

end sub


sub Install(iCommand)
		on error resume next
		Msg("Installing LANDesk Client...")
		
		objShell.Run iCommand,0,True
		Wait(20)
		
		Monitor(setupFile)		
		Msg("LANDesk Client has been installed!")		
end sub


sub Wait(time)
	on error resume next
    time =  time * 1000
	WScript.Sleep time
end sub


sub Monitor(procName)

'secondary method to make sure wait for exit works
		Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2")		
		cmd = 1
		
		Do While cmd = 1			
			Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = '" & procName & "'")
			If colProcesses.Count = 0 Then
				on error resume next
				'Process is not running
				cmd = 0
				Wait(4)
			Else
				'Process is running
				cmd = 1
				Wait(30)		
			End If
		Loop				
end sub


sub Msg(message)
	on error resume next
	objShell.Run "cmd /c echo " & message & ">" & msgFile,0,true
	Wait(4)
end sub


sub Splash()
	on error resume next
	'a simple animation I made (ldhta.exe is mshta.exe)
        'you'll have to create your own little animation here
	objShell.Run CurDir & "\ldhta.exe " &  CurDir & "\ldprogress.hta",9,false
	Wait(8)
end sub


sub ExitSequence(errorcode)	
	Msg("Exiting...")
	Wait(4)
	objShell.Run "taskkill /f /im ldhta.exe",0,true	
	WScript.Quit(errorcode)
end sub

C# – Elevation of Applications, Runas (Jump)

email me

This is a work in progress, but I have created a program to elevate a specified application. The idea is, you need to run an application under a restricted user profile, but cannot because it requires admin privileges—this gets around that. The program also bypasses UAC! Written in C#. I use the SecureStringProcessStartInfo, and MemoryStream classes to do exactly what I needed—securely elevate an application. Originally written for Windows 7 (back in 2014) to only elevate executable files, but I’m adding support for Windows 10 and scripting languages as well.

Current Features
   
 --Accepts executables
 --Accepts batch files
 --Accepts any passed parameters for program
 --Accepts an AES string for password
 --Accepts an encrypted reg key for password
 --Option to wait for program to exit
 --Create tighter try/catches (done 04/11/2017)
 --Remove second console window on batch files (done 04/14/2017) 
 --Create more methods from existing code (done 04/11/2017)
 --Add logging in registry (done 11/29/2017)
 --Add logging in event log (done 11/29/2017)
 --Add VBScript support (done 12/15/2017)

Future Ideas

 --Add a required pin number for internal script use
 --Add domain support 

 

AES Information

AES has three fixed 128-bit block ciphers with cryptographic key sizes of 128, 192 and 256 bits. Key size is unlimited, whereas the block size maximum is 256 bits. The AES design is based on a substitution-permutation network (SPN) and does not use the Data Encryption Standard (DES) Feistel network.

In 1997, the NIST initiated a five-year algorithm development process to replace DES and Triple DES. The NIST algorithm selection process facilitated open collaboration and communication and included a close review of 15 candidates. After an intense evaluation, the Rijndael design, created by two Belgian cryptographers, was the final choice.

AES replaced DES with new and updated features:

  • Block encryption implementation
  • 128-bit group encryption with 128, 192 and 256-bit key lengths
  • Symmetric algorithm requiring only one encryption and decryption key
  • Data security for 20-30 years
  • Worldwide access
  • No royalties
  • Easy overall implementation

 

How doe AES work?

 

What does the diagram mean?

• AES is a block cipher with a block length of 128 bits.

• AES allows for three different key lengths: 128, 192, or 256 bits.

• Encryption consists of 10 rounds of processing for 128-bit keys, 12 rounds for 192-bit keys, and 14 rounds for 256-bit keys.

• Except for the last round in each case, all other rounds are identical.

• Each round of processing includes one single-byte based substitution step, a row-wise permutation step, a column-wise mixing.

• To appreciate the processing steps used in a single round, it is best to think of a 128-bit block as consisting of a 4 × 4 matrix of bytes, arranged as follows:

• Therefore, the first four bytes of a 128-bit input block occupy the first column in the 4 × 4 matrix of bytes. The next four bytes occupy the second column, and so on.  more on AES…

 

Screenshot of Jump tool in action

 

Screenshot of elevation working

 

The Code (click to view source code)


using System;
using System.IO;                      // used by MemoryStream
using System.Diagnostics;             // used by Process
using System.Linq;                    // used by ToArray
using System.Security;                // used by SecureString
using System.Text;                    // used by Encoding
using System.Security.Cryptography;   // used by aes
using Microsoft.Win32;                // used by registry
using System.Collections.Generic;     // used by List (quotes)
using System.Text.RegularExpressions;

namespace Jump
{
    class JumpUtil
    {

        //////////////////////////////////////////////////
        // See all class declarations at the bottom
        //////////////////////////////////////////////////

        //////////////////////////////////////////////////
        // See notes at the bottom
        //////////////////////////////////////////////////


        static void Main(string[] args)

        {

            // CONSOLE HEADER
            //----------------------------------------------------
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("\nJump v1.0.0.1 December 2017");
            Console.WriteLine("\nLaunch Windows-based applications in elevated mode");
            Console.WriteLine("\nEddie Jackson | mrnettek@gmail.com | eddiejackson.net");
            Console.WriteLine("\nUsage: -app \"notepad.exe\" -opt \"name.txt\" -secure \"rEqnfiteGwLsktuW==\" -wait\n");

            // QUOTE
            // returns the random quote
            SubQuote();


            // BEGIN
            // load items into array
            // this loads arguments from the command line into an array
            foreach (string s in args)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    array = args[i].ToString();
                }

                // contains contents of array
                arrayString = arrayString + s.ToString() + " ";
            }
            // END - LOAD ITEMS INTO ARRAY            


            // SPACES
            // initialized to detect spaces and assign variables accordingly 
            // regex wasn't working properly when I added spaces
            string inputstring = arrayString.ToString();
            string[] inputstringarray = inputstring.Split(' ');



            // APP
            // does the command line contain the -app parameter?
            if (arrayString.Contains(parameterApp))
            {
                // found the -app parameter
                returnIndex = Array.IndexOf(inputstringarray, parameterApp);
                returnedApp = args[returnIndex + 1];                
               
                //returnedApp = FindNextValue(arrayString, parameterApp);  // regex doesn't work right. Disabled for now.
                if (returnedApp != parameterSecure &&
                    returnedApp != parameterOpt &&
                    returnedApp != parameterWait &&
                    returnedApp != "")
                {
                    appName = returnedApp;
                }
            }
            else
            {
                // the -app parameter is completely missing
                Messenger(Message1);
                Environment.Exit(6);
            }


            // OPTION
            // does the command line contain the -opt parameter?
            // I use string[] and IndexOf to read spaces in the options parameter
            // regex wasn't working properly when I added spaces
            if (arrayString.Contains("-opt"))
            {
                // found the -opt parameter
                returnIndex = Array.IndexOf(inputstringarray, parameterOpt);

                // return what follows the -opt parameter
                returnedOpt = args[returnIndex + 1];
                // accommodate extra spaces in file name - useful for vbs files
                if (returnedOpt == parameterSecure) {
                        returnedOpt = args[returnIndex + 0];
                    }

                // make sure returnedOpt isn't the AES variable
                if (returnedOpt.Contains("=="))
                {                    
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("\n\nMissing data from the -opt parameter!\n");
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Environment.Exit(6);
                }               

                // validate return option meets conditions
                if (
                    returnedOpt != parameterSecure &&
                    returnedOpt != parameterApp &&
                    returnedOpt != parameterWait &&
                    returnedOpt != "")
                {
                    // set options
                    appOpt = returnedOpt;               

                }
                else {

                    
                    // check for data following -opt parameter
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("\n\nMissing data from the -opt parameter!\n");
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Environment.Exit(6);
                }

            }



            // SECURE
            // does the command line contain the -secure parameter?
            if (arrayString.Contains(parameterSecure))
            {
                // found the -secure parameter
                returnedSecure = FindNextValue(arrayString, parameterSecure);
                if (returnedSecure != parameterApp &&
                    returnedSecure != parameterOpt &&
                    returnedSecure != parameterWait &&
                    returnedSecure != "")
                {
                    appPassword = (Decrypt(returnedSecure.ToString()));
                }
                else {

                    // check for data following -secure parameter
                    Messenger(Message2);
                    Environment.Exit(6);                    
                }
            }
            else
            {
                // the -secure parameter is completely missing                
                Messenger(Message6);                
                Environment.Exit(6);
            }
         

            // WAIT
            // does command line contain the -wait parameter?
            if (arrayString.Contains(parameterWait))
            {
                // found the -wait parameter
                appWait = "True";
            }
            else
            {
                // did not find the -wait parameter
                appWait = "False";

            }
            
            
            // DETERMINE FILE TYPE 
            // mostly made for handling batch files
            // had no issues with EXEs
            //----------------------------------------------------
            string retVBS = "FALSE";
            string retBAT = "FALSE";            
            string extension = Path.GetExtension(appName);

            if (extension.ToLower() == ".cmd") { retBAT = "TRUE"; }
            if (extension.ToLower() == ".bat") { retBAT = "TRUE"; }
            if (extension.ToLower() == ".vbs") { retVBS = "TRUE"; }            


            // BEGIN - ELEVATED APP LAUNCH            
            // use SecureString
            //----------------------------------------------------

            SecureString securePassword = new SecureString();
            Array.ForEach(appPassword.ToArray(), securePassword.AppendChar);
            securePassword.MakeReadOnly();

            // instantiate process from Process
            Process process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                // set up default properties
                UserName = appUser,
                Domain = "",
                Password = securePassword,
                LoadUserProfile = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };


            // CMD, BAT
            // IF A BATCH FILE, DO THIS
            // the reason I created this was because there is
            // an EXTRA black window when launching batch files 
            // using SecureString :: quite annoying MS hasn't 
            // done something about this
            //----------------------------------------------------
            if (retBAT == "TRUE")
            {
                try
                {
                    // DOES THE FILE EXIST???
                    if (!File.Exists(appName))
                    {
                        Messenger(Message10);
                        Environment.Exit(4);
                    }

                    startInfo.FileName = @"C:\Windows\SysWOW64\Wscript.exe";
                    startInfo.Arguments = "_hide.vbs";

                    string path = "_hide.vbs";
                    string text0 = "On error resume next:";
                    File.WriteAllText(path, text0);

                    // builds the vbscript
                    using (StreamWriter sw = File.AppendText(path))
                    {
                        string text1 = "";
                        string text2 = "";

                        if (appOpt != "")
                        {
                            // with option                            
                            text1 = "Set WshShell = CreateObject(\"WScript.Shell\"):";
                            text2 = "WshShell.Run chr(34) & " + "\"" + appName + "\"" + " & chr(34) & \" \" & chr(34) & " + "\"" + appOpt + "\"" + " & chr(34)" + ",0, true";
                                                       
                        }
                        else {
                            // without option                            
                            text1 = "Set WshShell = CreateObject(\"WScript.Shell\"):";
                            text2 = "WshShell.Run chr(34) & " + "\"" + appName + "\"" + " & chr(34)" + ",0, true";
                                                      
                        }

                        // writes the vbs to file
                        sw.WriteLine(text1);
                        sw.WriteLine(text2);
                    }

                    // instantiates the process
                    process = Process.Start(startInfo);

                    // checks to see if -wait is true
                    if (appWait == "True") { process.WaitForExit(); }

                    Console.ForegroundColor = ConsoleColor.Green;                    
                    Console.WriteLine("\nGreat Success!\n");
                    Console.ForegroundColor = ConsoleColor.White;

                    System.Threading.Thread.Sleep(1000);

                    // if this gets lost, I'll probably just add a %temp% path
                    if (File.Exists("_hide.vbs"))
                    {
                        File.Delete("_hide.vbs");
                    }
                    Audit();
                    Environment.Exit(0);
                }

                catch (Exception)
                {
                    Messenger(Message8);
                }
            }



            // VBS
            // IF A VBSCRIPT FILE, DO THIS
            //----------------------------------------------------
            if (retVBS == "TRUE")
            {
                try
                {
                    // DOES THE FILE EXIST???
                    if (!File.Exists(appName))
                    {
                        Messenger(Message10);
                        Environment.Exit(4);
                    }

                    startInfo.FileName = @"C:\Windows\SysWOW64\Wscript.exe";

                    if (appOpt != "")
                    {
                        //startInfo.Arguments = appName + " " + "\"" + appOpt + "\"";
                        startInfo.Arguments = "\"" + appName + "\"" + " " + "\"" + appOpt + "\"";
                        process = Process.Start(startInfo);                        
                        
                    }
                    else
                    {
                        startInfo.Arguments = "\"" + appName + "\"";
                        process = Process.Start(startInfo);
                    }

                    

                    if (appWait == "True") { process.WaitForExit(); }

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("\nGreat Success!\n");
                    Console.ForegroundColor = ConsoleColor.White;

                    System.Threading.Thread.Sleep(1000);
                    
                    Audit();
                    Environment.Exit(0);                    
                }
                catch (Exception)
                {
                    Messenger(Message8);
                }
            }


            // EXE
            // IF AN EXECUTABLE FILE, DO THIS
            //----------------------------------------------------

            // does app exist?                

            try
            {
                // I have added a little bit of extra logic for EXEs, specifically 'system' EXEs that may be in Windows or System32 folders
                // I append the .EXE and relative system paths just as an extra feature to find 'known' EXEs. Otherwise, EXEs like ping, 
                // calc, notepad, net, reg, etc., would fail without the path being explicitly defined
                if (!File.Exists(appName) && (!File.Exists(appName + ".exe")))
                {
                    if (!File.Exists("C:\\Windows\\" + appName + ".exe") && (!File.Exists("C:\\Windows\\" + appName)))
                    {
                        if (!File.Exists("C:\\Windows\\system32\\" + appName + ".exe") && (!File.Exists("C:\\Windows\\system32\\" + appName)))
                        {
                            Messenger(Message10);
                            Environment.Exit(4);
                        }
                    }
                }


                startInfo.FileName = appName;                
                if (appOpt != "") { startInfo.Arguments = "\"" + appOpt  + "\""; }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Elevating...");
                Console.ForegroundColor = ConsoleColor.White;

                process = Process.Start(startInfo);                

                if (appWait == "True") { process.WaitForExit(); }

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("\nGreat Success!\n");
                Console.ForegroundColor = ConsoleColor.White;
                Audit();
                Environment.Exit(0);
            }

            catch (Exception)
            {
                Messenger(Message8);
            }


        }
        // END - ELEVATED APP LAUNCH


        // RETURN NEXT VALUE        
        public static string FindNextValue(string inputArray, string inputSearch)
        {
            sNext = "";

            if (arrayString.Contains(inputSearch))
            {

                string[] sRegX = Regex.Split(inputArray, @"[^’a-zA-Z0-9\\\:\=\-\._]+");

                int index = Array.IndexOf(sRegX, inputSearch);
                if (index < sRegX.Count() - 1)
                    sNext = sRegX[index + 1];
            }

            return sNext;
        }

        
        // BASIC LOGGING
        static void Audit()
        {
            // create registry key

            string reg1 = "HKEY_CURRENT_USER";
            string reg2 = @"SOFTWARE\Jump\";
            string regPath = reg1 + @"\" + reg2;
            string UName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            string regVal = appName + " " + UName;
            
            DateTime dt = DateTime.Now;
            Registry.SetValue(regPath, dt.ToString(), regVal, RegistryValueKind.String);

            
            // log event

            string sSource;
            string sLog;
            string sEvent;

            sSource = "Jump.exe";
            sLog = "Application";
            
            sEvent = appName + " was installed using the Jump tool by " + UName;

            if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);

            EventLog.WriteEntry(sSource, sEvent);

            // output to console
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("{{{ Security log has been updated }}}\n");
            Console.ForegroundColor = ConsoleColor.Gray;
        }
                    


        
        // Just show header of jump util

        static void Help()
        {
            Console.ForegroundColor = ConsoleColor.White;
            Environment.Exit(0);
        }

        // import and show message
        static void Messenger(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("\n{0}\n", message);
            Console.ForegroundColor = ConsoleColor.White;
            Environment.Exit(2);
        }


        // returns random quote
        static void SubQuote()
        {
            QuoteGenerator quoteGenerator = new QuoteGenerator();
            string retQuote = quoteGenerator.ReturnRandomQuote();
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("{0}\n", retQuote);
            Console.WriteLine("");
            Console.ForegroundColor = ConsoleColor.White;
        }

       
       
        // decoding
        public static string Decrypt(string strData)
        {
            try
            {
                if ((strData.Length % 4) == 0)
                {
                    //aes string length is good
                    return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));
                }

                Messenger(Message9);
                Environment.Exit(6);             
                return null; 

            }
            catch (Exception)
            {
                Messenger(Message9);
                Environment.Exit(6);                
                return null; // prevents return error message
            }         
}

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {

            try
            {
                PasswordDeriveBytes passbytes =
                new PasswordDeriveBytes(strPermutation,
                new byte[] {            bytePermutation1,
                                        bytePermutation2,
                                        bytePermutation3,
                                        bytePermutation4
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.passwordderivebytes%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
            });
                

                MemoryStream memstream = new MemoryStream();
                Aes aes = new AesManaged();
                aes.Key = passbytes.GetBytes(aes.KeySize / 8);
                aes.IV = passbytes.GetBytes(aes.BlockSize / 8);
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged(v=vs.110).aspx

                CryptoStream cryptostream = new CryptoStream(memstream,
                aes.CreateDecryptor(), CryptoStreamMode.Write);
                cryptostream.Write(strData, 0, strData.Length);
                cryptostream.Close();
                return memstream.ToArray();
                //Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream(v=vs.110).aspx
            }
            catch (Exception)
            {
                Messenger(Message8);
                Environment.Exit(6); // exits in case the password fails
                //return strData;
                return null; // prevents return error message
            }

        }

        class QuoteGenerator
        {
            Random random = new Random();
            List<string> Quotes = new List<string>();

            public QuoteGenerator()
            {
                Quotes.Add("Intelligence is the ability to adapt to change - Stephen Hawking");
                Quotes.Add("Nothing endures but change - Heraclitus");
                Quotes.Add("Dream big and dare to fail - Normal Vaughan");
                Quotes.Add("If it doesn’t challenge you, it won’t change you - Fred DeVito");
                Quotes.Add("Genius is talent set on fire by courage Henry Van Dyke");
                Quotes.Add("Energy and persistence conquer all things - Benjamin Franklin");
                Quotes.Add("The secret of getting ahead is getting started - Mark Twain");
                Quotes.Add("The measure of who we are is what we do with what we have - Vince Lombardi");
                Quotes.Add("With self-discipline most anything is possible - Theodore Roosevelt");
                Quotes.Add("The price of greatness is responsibility - Winston Churchill");
                Quotes.Add("Action is the foundational key to all success - Picasso");
                Quotes.Add("Try not to become a man of success, but rather a man of value - Albert Einstein");
                Quotes.Add("Learning never exhausts the mind - Leonardo da Vinci");
            }

            public string ReturnRandomQuote()
            {
                int quoteCount = Quotes.Count;
                int randomNumber = random.Next(0, (quoteCount - 1));
                return Quotes[randomNumber];
            }
        }


        // the admin user account name
        public const string appUser = "Administrator";        

        // use these permutations - change these
        public const string strPermutation = "eqyshqfqhjk";
        public const int bytePermutation1 = 0x11;
        public const int bytePermutation2 = 0x19;
        public const int bytePermutation3 = 0x17;
        public const int bytePermutation4 = 0x11;

        public const string strRegHive = "HKEY_LOCAL_MACHINE";
        public const string strRegKey = @"SOFTWARE\Serial\";
        public const string strRegPath = strRegHive + @"\" + strRegKey;
        public const string strRegVal = "Serial1";

        // general console messages
        public const string Message1 = "Slow down there, Skippy. Did you forget the -app parameter?";
        public const string Message2 = "Ohhh, man...did you forget to add the AES string?";
        public const string Message3 = "Yo, where is the -opt parameter? Use -opt.";
        public const string Message4 = "Wait a minute. Looks like -wait is missing.";
        public const string Message5 = "Hey, dude, you forgot to enter an app name.";
        public const string Message6 = "Houston, we have a problem. Did you forget to add the -secure parameter?";
        public const string Message7 = "Too much, man...too much. You have too much in the command line.";
        public const string Message8 = "Hold on, Chief. This isn't good...the app wasn't elevated.";
        public const string Message9 = "Come on man...the AES string is too short.";
        public const string Message10 = "The file seems to have taken a vacation. It can't be found!";        

                
        // the array, working space
        public static string array = "";

        // the items in the array
        public static string arrayString = "";

        // appVar(i) becomes appName, appOpt, appWait, appPassword            
        public static string appPassword = "";
        public static string appName = "";
        public static string appOpt = "";
        public static string appWait = "";
        private static string sNext;

        public static string parameterApp = "-app";
        public static string parameterWait = "-wait";
        public static string parameterOpt = "-opt";
        public static string parameterSecure = "-secure";        
        public static string returnedApp = "";
        public static string returnedSecure = "";
        public static string returnedOpt = "";
        public static int returnIndex;
    }

}

/*NOTES

       SPACES IN THE DECRYPT STRING
       64-bit encoding does not work well with spaces in the string for some odd reason. 
       Add the following: stringToDecrypt = stringToDecrypt.Replace(" ","+");
       before this line "int len = stringToDecrypt.Length; inputByteArray = Convert.FromBase64String(stringToDecrypt);"
       to replace blank spaces with '+'. Plus sign will be interpreted as a space when you call the FromBase64String method.

       EXTRA BLACK WINDOW (CONSOLE WINDOW)
       When using SecureString, and passing a username and password to a BATCH file process, an EXTRA black window appears.
       The window is tied to the batch file :-( , and from what I can tell, cannot be so easily hidden. Yes, you can hide the main
       process window, but not the child window. If you close the child window, it kills the batch file. Arrrrrg.
       I was able to create a workaround using VBS output and hiding the batch process, but I will be looking for a better solution.

*/



 

Screenshot of Visual Studio (click to zoom)

* no longer uses a password – I’m passing in an AES string

Fun Fact

It would take a supercomputer 1 billion billion years to crack the 128-bit AES key using brute force attack. This is more than the age of the universe (13.75 billion years).