Is there a way to reinstall an application in SCCM 2012? - software-distribution

In SCCM 2007, there were several "Right Click Tools", and with their help it was possible to "reinstall" a package. In SCCM 2012 I still couldn't find a way, how could I reinstall an application?
Let me explain:
I created an installation package from a software, then distributed it as an "Application". Installation finished successfully. One week later a user calls, he is having trouble with this application. The package I created supports the reinstallation(either by removing the software and installing it again, or with a repair functionality). But, in SCCM I have no option(neither found a right click tool which could do that), to reinstall the package. I have to remove it, and then install it again.
I thought I could write a program to that, and create my own "Right Click Tool", but I can't find any information what exactly should I do?
So my questions are:
- Is there a Right Click Tool which can reinstall an application somehow?
- Is there some documentation, where I could get some information about this issue?
I am sure, many others have the same problem.
Or I didn't find a way, because there is none? :(
Thanks in advance!

In our company we would also have to liked this and did some basic research but as it seems no one has done it so far (doesn't mean it's impossible). We also talked to two Microsoft SCCM consultants about it and both said there is currently no way.
The thing is applications are all about the detection method. It is the only thing that will trigger the setup. So if you have a software, and you don't want to deploy it as package (this is still possible and they can still be rerun with tools like Roger Zanders client center), what you can do is use a detection method that you can influence. Like a file or reg key, which you can remove remotely. The application deployment evaluation cycle can be triggered remotely just like all other client actions so this would not be a problem.
Sadly this is only a workaround and I would very much like if someone proves me wrong but so far this is the best we could come up with.
Edit:
So you motivated me to dig a little deeper and I also got some really good slides from Microsoft and I found some possible approach:
As the application is all about detection all the time my idea is to fake it.
As far as I can tell detection methods are saved in some crazy xml format in the WMI in root\ccm\CIModels in the Class Local_Detect_Synclet. So I wrote a script that goes there and replaces the detection method with an empty detection method that checks for a file. It has no properties so it can never work. After that I call the enforce method on my application using the class CCM_AppDeliveryType in the same namespace. It takes an AppdeliveryTypeID and the current revision but both of those can be seen in CCM_AppDeliveryTypeSynclet. After the enforce reinstalled the program I reset the detection method to the old one and trigger a second enforce which will do nothing but tell the system the app is properly detected. The Vbscript that does all this looks like this:
computername = "WS0000xxxx"
Set wmiCIModels = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels")
Set wmiAppDeliveryType = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels:CCM_AppDeliveryType")
deploymentTypeID = "ScopeId_79903130-730F-48B7-8165-6088B83359BE/DeploymentType_68a80836-208e-401b-a69f-ae4c184b9f85"
Set installedDelTypes = wmiCIModels.ExecQuery("select * from Local_Detect_Synclet where AppDeliveryTypeId = '" & deploymentTypeID & "'" )
For Each instDelType In installedDelTypes
strOldDetectionMethod = instDelType.ExpressionXml
instDelType.ExpressionXml = "<LocalDetectionMethod><Settings><File></File></Settings><Rule xmlns=""http://schemas.microsoft.com/SystemsCenterConfigurationManager/2009/06/14/Rules""><Expression><Operator>Equals</Operator><Operands><SettingReference AuthoringScopeId="""" DataType=""Version"" SettingLogicalName=""X"" Method=""Value""/><ConstantValue DataType=""Version""/></Operands></Expression></Rule></LocalDetectionMethod>"
instDelType.Put_ 0
wmiAppDeliveryType.EnforceApp deploymentTypeID, "4", "", "Install", "", "1"
instDelType.ExpressionXml = strOldDetectionMethod
instDelType.Put_ 0
wmiAppDeliveryType.EnforceApp deploymentTypeID, "4", "", "Install", "", "1"
Next
The ExpressionXML is horribly long but I deleted everything from it by trial and error that seems possible.
For simplicity I hardcoded the AppdeliveryTypeID and revision but you can get a list of those, including nice names, with the following query:
Set wmiCIModels = GetObject("winmgmts:\\" & computername & "\root\ccm\CIModels")
Set delTypes = wmiCIModels.ExecQuery("select * from CCM_AppDeliveryTypeSynclet" )
For Each delType In delTypes
WScript.Echo "Deployment Name: " & delType.AppDeliveryTypeName & VbCrLf & "AppdeliveryTypeID: " & delType.AppDeliveryTypeId & VbCrLf & "Revision: " & delType.Revision & VbCrLf
Next
This also presents on of the biggest downsides I found so far. It is only possible to easily get the names of the AppDeliveries. These are not the names the application will show in the Software Center for example. I looked into translating this but the only method I found so far is to query the SCCM DB itself and the query is horribly complicated and needs of course some SCCM admin to execute it.
As with all WMI scripts you can execute it remotely by specifying a computer name or locally if you use '.', so you could use the SCCM Console Extension system and build your own right-click tool based on this.
This will work even on Applications that are not installed similar to the rerun of packages. If you do not want this you can check against CCM_AppDeliveryType to only see the installed applications.

Related

Creating an MSI or Script to deploy an EXE through AD

First:
I know there are other questions that ask similar/the same thing, I have looked at them tried all of them but no solution has helped.
The problem:
We use Epson Iprojection (downloaded from here: https://www.epson.co.nz/products/projectors/software/) However I can not find a way to get an MSI out of it (I am starting to think there is no MSI bundled in the .exe), and I can not seem to install it through CMD on computer start using AD. Any help will be greatly appreciated.
Vague Answer: Let me try to formulate an answer out of those messy comments above. I only briefly tested this software, it might not deploy as badly as expressed. Remember that this is a generic answer for whoever would find this in the future, and not for OP per-se (there is no real answer in here).
Due Diligence: I always try to consult package tip databases if I have problems with a package. Somebody, somewhere will have seen the same problem (eventually).
Silent Installation: Silent installation of legacy setups is usually possible (not always), but never really reliable. For Installshield it involves recording answer files (setup.iss) that record dialog answers. However, unknown dialogs can show up suddenly on some systems (low disk space, reboot prompts, unexpected lock or application in-use warnings, unexpected service running warnings,etc...) and hence halt the install unexpectedly as the response file has no recorded value for the dialog in question. This particular Epson setup also has an unfortunate reboot requirement on uninstall that is hard to deal with for large scale deployment (spontaneous reboot likely - without warning).
Repackaging: Personally I would try to capture the install using a repackaging tool. Most of these are expensive, but can output MSI, MSIX or other deployment package types. Repackaging fails when the package contains complex, custom logic that - for example - create dynamic content (ciphers, unique GUIDs, etc...) and in a number of very specific technical cases.
Contact Vendor: If you capture an MSI that doesn't work, why not try to send it back to the vendor with some comments on how hard this software is to deploy and maybe mention the major benefits of MSI? I would tell them you have to ditch the whole software from your network if they can't deliver a deployment solution that works. Time is of the essence. "Some solutions are only free if your time is worthless" (quote from Joel Spolsky himself - slightly out of context, but the same issue: we need solutions that work in a timely fashion).
Note: I once had to compile a special setup to deal with a client's
deployment problem that was our fault. Deployment problems need fixing at a standardization level. Standards!
Buried within the single-exe download is iProjection_inst.exe, some sort of wrapper that prompts for language selection, and doesn't seem to have a standard "non-interactive" mode.
Inside this is instData\Setup.exe, a vintage "full screen" InstallShield installer with external ini / cab files.
Running this with Setup.exe /? doesn't give any command line arguments, as it would for a modern InstallShield setup.exe.
Although it supports recording an answer file via Setup.exe /r, when I try to replay the answer file with Setup.exe /s it seems to still prompt for EULA, and then fails to install.
So this is really a design flaw in the innermost installer to do with the dialog sequence.
Assuming Epson won't fix it and repackaging is too hard, a hacky alternative is to use Powershell to automate the UI of instData\Setup.exe once the "Welcome" screen is showing, but I don't think this will work running as an AD script.
$wshell = New-Object -ComObject wscript.shell
$aName = "Epson iProjection Setup"
function Next() {
if ($wshell.AppActivate($aName)) {
$wshell.SendKeys(' ');
start-sleep 1;
}
}
function AcceptEula() {
if ($wshell.AppActivate($aName)) {
$wshell.SendKeys("{TAB}");
$wshell.SendKeys("{TAB}");
$wshell.SendKeys(' ');
start-sleep 1;
}
}
Next; AcceptEula; AcceptEula; start-sleep 20; Next;
I know this is an old thread but it looks like it may be easy now. The latest 2.41 from here
http://www.downloads.epson.com.au/DownloadFile.asp?filename=iProV2411Win%5FWEB%2Eexe&path=Drivers
seems to have an MSI in it. Just jump into the %temp% folder and organize by date so you can see the latest files. Run the installer and a new folder named with a GUID should show up, in my case {27CDEEE8-B6F2-45a7-A48E-696862573D9B}.
Under this folder there is a series of InstData folders like InstDataX64 where you can find an MSI.

VBscript, which will MAKE a local user change their password at next login

Ok, so I have been going at this forever now and I am finding no answers to this that actually work. So, I am trying to create a Script which will make a local user change their password when they next logon. I have looked and looked and looked, but nothing helps. Though I feel like I’m close but missing something. Now I will say I am very, very new to scripting in general so sorry if I seem dumb, but I’d love the help. Also, I am using Windows 10 (not sure if that will make a difference). I am also creating this for a school assignment and I did ask my teacher for a hand, but it’s been a week sense I have heard anything. Thank you!
Now here is what I have:
strComputer = "LAPTOP-56BDJGPQ"
Set usr = GetObject("WinNT://LAPTOP-56BDJGPQ/Guest,user")
usr.Put "PasswordExpired", 1
usr.SetInfo
Now, I know that maybe where it says /Guest,user might be incorrect but I have also tried using my account which is the admin, even that seem to do nothing.
Here is what happens when I run it (now, I do run everything through command prompt)
c:\Comp230>cscript USER_Logon_reset.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
c:\Comp230>
Now this to me shows it ran, but when I go to test to see if it worked well nothing happens.
I will say I have tried other ways of scripting this part like replacing usr.Put to objUser.Put, etc. I would love any input I could get because this is frustrating.
If the Password Never Expires flag is set, you need to delete it first to expire the password.
Try the following instead.
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000 ' 65536
Set usr = GetObject("WinNT://LAPTOP-56BDJGPQ/JohnDoe,user")
currentFlags = usr.Get("UserFlags")
'check if "password never expires" flag is set. if so, remove it
If currentFlags And ADS_UF_DONT_EXPIRE_PASSWD Then
newFlags = currentFlags - ADS_UF_DONT_EXPIRE_PASSWD
'setting new flags
usr.Put "UserFlags", newFlags
End If
usr.Put "PasswordExpired", 1
usr.SetInfo
You may also need to remove the User Cannot Change Password flag if it's set.

How do demo-versions know the test-time is over after re-installing?

How do applications like CloneDVD2 or AnyDVD know that the free phase is over, even if the application was uninstalled and then re-installed? Those applications don't require the user to login so that they could identify the user again.
Also on deinstalling them a window pops up asking whether the "registration files" should be kept or not. Even if they are not kept, the re-installed application knows the demo-time is over.
How is that technically realized?
Could be everything...
You might reverse the algorithm to find out.
But to name an example:
It's possible to generate a hash, based on unique hardware identifiers, of your hardware configuration and send that over the internet to a database.
If your hash exists over there, the software knows you ran it before.
An other option is leaving tracking information inside of your OS. So the checkbox: delete register information, isn't deleting everything.
To test:
1) Switch GPU or CPU :P
2) Format & Reinstall computer

Running JMeter script using VBScript as automated test in HP ALM

So I'm trying to run JMeter from ALM. I have a bunch of scripts that will do load testing. At this point, I'm grasping at straws to get anything working. Originally I wanted to use LoadRunner, but I can't figure out how to actually run the scripts I have developed in that application either.
That said: I have written some code just to attempt to run the JMeter application with the relevant script. As I understand it, ALM runs the VBS locally, so local paths should work, and running software installed on a local machine should work...
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Exec "C:\Users\[path]\apache-jmeter-2.12\bin\jmeter.bat -t C:\Users\[path]\script.jmx"
This executes fine, but when looking at it, nothing appears. Ideally I'd have this run with no GUI (-n flag for jmeter), but I want to at least verify that the thing even starts up.
Currently nothing is happening, and I can't figure out what to do. I've attempted loops that wait until something happens, but they end up being infinite loops.
Any help would be greatly appreciated. Or...if you know of a resource that could actually help run either LoadRunner or JMeter scripts from ALM, I would be so grateful.
Thanks!
Maybe your ALM script doesn't respect underlying OS properties like JAVA_HOME or you don't have java executable in your PATH variable.
Try changing your line to look as follows:
objShell.Exec "c:\java\bin\java.exe -jar C:\Users\[path]\apache-jmeter-2.12\bin\ApacheJMeter.jar -t C:\Users\[path]\script.jmx"
to see how it goes.
By the way, there are several more ways of launching JMeter test, to learn about options check out 5 Ways To Launch a JMeter Test without Using the JMeter GUI guide, hopefully it will help to identify and apply the best integration approach.
Why......What is optimal for performance unit tests is not optimal for performance business tests. You also have people building tests for JMETER who it is not their primary focus to engage in performance testing. The requirements will be soft, the data sparse, the liberties on think time and pacing great. You are looking at a low value path. This perspective comes from a reformed developer.
Just rebuild them natively. Your value will be higher and a better match to the requirements you are looking to validate. Need a starting point? Execute your JMETER scripts with the target of your LoadRunner recording proxy. Input = JMETER requests, output = native LoadRunner code (in C). No funky library compromises for trying to have one tool execute another one.
If you are hellbent on pursuing this path and cannot/will not be dissuaded then consider the JAVA template virtual user. This is likely your best path, assuming you are licensed for it. You will also find that the odds are close to certainty that you will spend more time achieving a stable model than you will in just rebuilding the existing test code.
Try this :
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Exec """C:\Program Files\apache-jmeter-2.13\bin\JMeter.Bat"" -n -t ""C:\Program Files\apache-jmeter-2.13\bin\templates\DMS_APP.jmx"""

WMI "installed" query different from add/remove programs list?

Trying to use WMI to obtain a list of installed programs for Windows XP. Using wmic, I tried:
wmic /output:c:\ProgramList.txt product get name,version
and I get a listing of many of the installed programs, but after scrubbing this list against what "Add/Remove Programs" displays, I see many more programs listed in the GUI of Add/Remove Programs than with the WMI query. Is there another WMI query I need to use to get the rest of the programs installed? Or is there some other place I need to look for the rest?
Also, there are two installed programs that are listed in the WMI query that aren't in Add/Remove programs. Any idea why?
I believe your syntax is using the Win32_Product Class in WMI. One cause is that this class only displays products installed using Windows Installer (See Here). The Uninstall Registry Key is your best bet.
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
UPDATE FOR COMMENTS:
The Uninstall Registry Key is the standard place to list what is installed and what isn't installed. It is the location that the Add/Remove Programs list will use to populate the list of applications. I'm sure that there are applications that don't list themselves in this location. In that case you'd have to resort to another cruder method such as searching the Program Files directory or looking in the Start Menu Programs List. Both of those ways are definitely not ideal.
In my opinion, looking at the registry key is the best method.
All that Add/Remove Programs is really doing is reading this Registry key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
Besides the most commonly known registry key for installed programs:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
wmic command and the add/remove programs also query another registry key:
HKEY_CLASSES_ROOT\Installer\Products
Software name shown in the list is read from the Value of a Data entry within this key called: ProductName
Removing the registry key for a certain product from both of the above locations will keep it from showing in the add/remove programs list. This is not a method to uninstall programs, it will just remove the entry from what's known to windows as installed software.
Since, by using this method you would lose the chance of using the Remove button from the add/remove list to cleanly remove the software from your system; it's recommended to export registry keys to a file before you delete them. In future, if you decided to bring that item back to the list, you would simply run the registry file you stored.
I have been using Inno Setup for an installer. I'm using 64-bit Windows 7 only. I'm finding that registry entries are being written to
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
I haven't yet figured out how to get this list to be reported by WMI (although the program is listed as installed in Programs and Features). If I figure it out, I'll try to remember to report back here.
UPDATE:
Entries for 32-bit programs installed on a 64-bit machine go in that registry location. There's more written here:
http://mdb-blog.blogspot.com/2010/09/c-check-if-programapplication-is.html
See my comment that describes 32-bit vs 64-bit behavior in that same post here:
http://mdb-blog.blogspot.com/2010/09/c-check-if-programapplication-is.html?showComment=1300402090679#c861009270784046894
Unfortunately, there doesn't seem to be a way to get WMI to list all programs from the add/remove programs list (aka Programs and Features in Windows 7, not sure about Vista). My current code has dropped WMI in favor of using the registry. The code itself to interrogate the registry is even easier than using WMI. Sample code is in the above link.
Not the best, but whether it is practical method:
Use HijackThis. (Old version: HijackThis)
Run hijack this, click the "Open the Misc Tools section" button
click "Open Uninstall Manager"
click save list (*.txt), yes to the prompts, notepad will open with your add/remove programs list.
Source
You can get it in one line with powershell and batch file :
#echo off
Powershell /command "Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-List"
Pause
Installed products consist of installed software elements and features so it's worth checking wmic alias's for PRODUCT as well as checking SOFTWAREELEMENT and SOFTWAREFEATURE:
wmic product get name,version
wmic softwareelement get name,version
wmic softwarefeature get name,version
You can use the script from http://technet.microsoft.com/en-us/library/ee692772.aspx#EBAA to access the registry and list applications using WMI.
Hope this helps somebody: I've been using the registry-based enumeration in my scripts (as suggested by some of the answers above), but have found that it does not properly enumerate 64-bit software when run on Windows 10 x64 via SCCM (which uses a 32-bit client). Found something like this to be the most straightforward solution in my particular case:
Function Get-Programs($Bits) {
$Result = #()
$Output = (reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall /reg:$Bits /s)
Foreach ($Line in $Output) {
If ($Line -match '^\s+DisplayName\s+REG_SZ\s+(.+?)$') {
$Result += New-Object PSObject -Property #{
DisplayName = $matches[1];
Bits = "$($Bits)-bit";
}
}
}
$Result
}
$Software = Get-Programs 32
$Software += Get-Programs 64
Realize this is a little too Perl-ish in a bad way, but all other alternatives I've seen involved insanity with wrapper scripts and similar clever-clever solutions, and this seems a little more human.
P.S. Trying really hard to refrain from dumping a ton of salt on Microsoft here for making an absolutely trivial thing next to impossible. I.e., enumerating all MS Office versions in use on a network is a task to make a grown man weep.
With time having moved on quite a bit since this question was asked...
There's a WMI class available these days for the Uninstall entries in the registry. This is much quicker to reference than Win32_Product, which I think also runs verification on the list and can take a while to enumerate. The below Powershell code (possibly requires Powershell 3 or later) will list all entries (The Out-Gridview part is just for a pretty display).
Get-CimInstance Win32Reg_AddRemovePrograms | Out-gridview
Add/Remove Programs also has to look into this registry key to find installations for the current user:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall
Applications like Google Chrome, Dropbox, or shortcuts installed through JavaWS (web start) JNLPs can be found only here.
In order to build a more-or-less reliable list of applications that appear in the "Programs and Feautres" in the Control Panel, you have to consider that not all applications were installed using MSI. WMI only provides the ones installed with MSI.
Here is a short summary of what I've found out:
MSI applications always have a Product Code (GUID) subkey under HKLM\...\Uninstall and/or under HKLM\...\Installer\UserData\S-1-5-18\Products. In addition, they may have a key that looks like HKLM\...\Uninstall\NotAGuid.
Non-MSI applications do not have a product code, and therefore have keys like HKLM\...\Uninstall\NotAGuid or HKCU\...\Uninstall\NotAGuid.
I adapted the MS-Technet VBScript for my needs. It dumps Wow6432Node as well as standard entries into "programms.txt"
Use it at your own risk, no warranty!
Save as dump.vbs
From command line type: wscript dump.vbs
Const HKLM = &H80000002
Set objReg = GetObject("winmgmts://" & "." & "/root/default:StdRegProv")
Set objFSO = CreateObject("Scripting.FileSystemObject")
outFile="programms.txt"
Set objFile = objFSO.CreateTextFile(outFile,True)
writeList "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\", objReg, objFile
writeList "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\", objReg, objFile
objFile.Close
Function writeList(strBaseKey, objReg, objFile)
objReg.EnumKey HKLM, strBaseKey, arrSubKeys
For Each strSubKey In arrSubKeys
intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, "DisplayName", strValue)
If intRet <> 0 Then
intRet = objReg.GetStringValue(HKLM, strBaseKey & strSubKey, "QuietDisplayName", strValue)
End If
objReg.GetStringValue HKLM, strBaseKey & strSubKey, "DisplayVersion", version
objReg.GetStringValue HKLM, strBaseKey & strSubKey, "InstallDate", insDate
If (strValue <> "") and (intRet = 0) Then
objFile.Write strValue & "," & version & "," & insDate & vbCrLf
End If
Next
End Function
I had the same issue with the WMIC command only showing a subset of all installed programs. I needed a command that would output a CSV file of all the installed programs in Windows 10 and I wanted to make it easy for colleagues to run. The following Powershell command seems to work well, running much quicker than the WMIC command; it will generate a CSV in the user's Documents folder called AppsInstalled.csv with programs sorted by name, and with empty lines removed (numerous blank lines were returned in my tests for some reason?).
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate| Where-Object DisplayName -ne $null | Sort-Object -Property DisplayName | Export-Csv "$($env:USERPROFILE)\Documents\AppsInstalled.csv" -NoTypeInformation

Resources