Action in my task always ends with exit code 1. When I run the failed command locally on the server from a command line, it succeeds without problems. This is the output of the action:
Nevertheless, the last row is returned with exit code 1 and the command is not performed.
A little background: I need to replace a certificate for SCOM monitoring agent, that is about to expire, with a new one. For this testing run I first uploaded the certificate file (cert_{dns name}.crt) to a server with a software deployment task and then I ran this task separately. That’s why two of the rows are put to comment. The last command shall “pair” the new certificate with SCOM. unfortunately the tool can’t identify the certificate by anything else than the subject name, that’s why the rather complicated structure of the powershell script, testing if there are multiple certificates with the same name. If there are, the task can’t be done remotely and has to be done manually, because you need the gui to select, which certificate to pair with SCOM. Everything works fine, except the last command does not work and returns exit code 1. What does that mean? This is the relevant part from BF log:
I’m pretty sure this is correct. The powershell script was executed normally and all actions to be performed by it were executed properly. And yes, the quotation really looks strange, but it’s the correct way to run a powershell command from a command line.
I later tried to put the last row into an “if” condition like: if {line 1 of file “import-result.txt” of folder “C:\SCOM\cert” contains “imported”} (I didn’t forget the endif command of course), but the script is not even executed and reports a syntax error after the action is evaluated. I checked for any typos very carefully, but can’t find one. Is it possible, that the script is searching for the file “import-result.txt” before the script starts? In that case, how can I limit the execution of the last command only to the case the file contains the required information?
I’ll try the redirection, but it will take some time before I have an opportunity to test it, I can’t do it without a real business justification.
Furthermore, what confuses me even more, the same fixlet contains another action, which ends with exactly the same command as this one (it is meant to import a certificate to newly activated server, which doesn’t have any old certificates present). In this second action, the command works fine.
Is it possible, that the script is searching for the file “import-result.txt” before the script starts?
Yes, that’s exactly what’s happening in fact. When an actionscript contains a ‘prefetch’ statement, the action is evaluated before it runs, and every relevance substitution is checked. If the evaluation results in an <error> result (such as the file not existing yet) then you’ll encountet this problem.
There are a couple of ways around the error. The easiest in this case is probably to change the downloads to use a prefetch block; in that case only the portion of the script inside the prefetch block is evaluated before the script executes. Other workarounds include things like changing the statement to handle error checking. Some examples might be if {if (active of action) then ([evaluate the file]) else false}
Or if {if exists true whose ([evaluate the file]) else false}
Or catch errors with the pipe ‘|’ operator if {[evaluate the file] | false}
So, in short, try to fix the execution by using action uses wow64 redirection false, and try to fix the pre-action evaluation using a prefetch block or changing your relevance statements to catch errors before the output file is generated.
waithidden powershell.exe -ExecutionPolicy Bypass -NonInteractive -Command "& "“C:\SCOM\cert\CertImport.ps1"”"
continue if {line 1 of file “import-result.txt” of folder “C:\SCOM\cert” contains “imported”}
waithidden cmd /c c:\SCOM\cert\MOMcertipmort.exe /SubjectName {dns name}
After the //certificate file line would always come the lines generated by the windows software distribution wizard, which I always use to create the prefetch block. In this case I will have to replace “prefetch” with “add prefetch item” then.
Hm, after clicking on OK, the fixlet reports “argument not recognised” on line 3 (add prefetch item). I never used prefetch block so far, but as I checked the syntax on the web it seems correct. So where’s the problem?
Hm, that constitutes a huge problem, because the fixlet shall be used by not only me, but also other colleagues, who are not that proficient with BigFix, and modifying the command could be quite difficult for them to do it correctly. And as I said, it’s necessary to first generate the prefetch command together with extract by using the wizard and then add them to the action script before running the action. If it was possible by using standard prefetch, then it’s quite simple - copy/paste the first two lines from the wizard as-is to the action script. Furthermore, I just found out, that the extract command must be placed outside the prefetch block. So it will not only be necessary to rewrite the prefetch command (add the name and url arguments, change colons for equals, change “prefetch” to “add prefetch item”) but also copy/paste prefetch and extract lines separately. All that leaves huge space for possible typo or other type of error. I guess I’ll have to go with another option than prefetch block. I’ll let you know how does it all work, as soon as I have some business justification to use the fixlet.
It doesn’t look like you’ve escaped all of the opening curly brackets in the powershell script. every opening curly bracket “{” should be doubled up “{{” otherwise bigfix will think you are trying to do some relevance substitution.
As I said, the powershell script is fine. I discovered, that when there is nothing else than { in the row, doubling is not necessary. So I didn’t do that - anything not necessary is harmful, basically.
I fear it’s some error in the file that is executed on the last row, which then wouldn’t have any solution except for Microsoft to fix it.
So in the end I used completely different approach. I searched for what exactly does the momcertimport file do and discovered, that it just writes the thumbprint of the certificate to registry value. So instead of running the file, which always failed, I changed the registry value to the thumbprint of the certificate I just imported. So problem was basically solved, even though in a different way.