I have a problem when using the JiraPS Module in a script.
When executing the script below I receive a line-break instead of an actual result. The weird thing is, when executing the script twice, once without the Get-JiraProject -Project 'exampleBoard' at the bottom and once with only the Get-JiraProject -Project 'exampleBoard' everything works fine and I get the correct output. When using Get-JiraProject in the script which outputs all projects with read-access I get a line-break for every project.
param ($jirauser)
$ServerURi = 'https://company.atlassian.net'
if (!(
(Get-Module BetterCredentials -ListAvailable) -and
(Get-Module JiraPS -ListAvailable)
)) {
$Force = $True
}
if ($Force) {
# Force the installation of the latest version of the modules
Install-Module -Name BetterCredentials -Scope CurrentUser -AllowClobber -Force
Install-Module -Name JiraPS -Scope CurrentUser -Force
}
# Set Jira server and create session
Import-Module JiraPS -Force
Set-JiraConfigServer $ServerURi
# Get credentials with "BetterCredentials" and store them if they are new
Import-Module BetterCredentials -Force
$cred = Get-Credential -UserName $jirauser -Store
#Session Creation
Write-Output "Creating a session"
$session = New-JiraSession -Credential $cred
if ($session) {
Write-Output $session
}
Get-JiraProject -Project 'exampleBoard'
The output looks as follows:
The value of jirauser is: example#company.com
Creating a session
Username WebSession
-------- ----------
example#company.com Microsoft.PowerShell.Commands.WebRequestSession
I tried the following already:
Running the script inside WSL and PWSH to work around Execution Policies
Using / not using BetterCredentials
Split the code in two (as described above) and ran it twice
Writing the output of Get-JiraProject into a variable and printing the variable instead
Using New-Object System.Management.Automation.PSCredential to create the credentials manually
Sleep for a few seconds after authenticating
I tried to run a Powershell Script under the System Account via Jenkins.
$DebugPreference = 'Continue'
$dt=get-date -Format "MM-dd-yyyy-HH-mm-ss-fff"
Start-Transcript -Path "C:\install\transcript-$dt.txt"
dir env:
$cmdline = $((Get-CimInstance win32_process -Filter "ProcessID=$PID" | ? { $_.processname -eq "pwsh.exe" }).commandline)
if($cmdline -like "*pwsh.exe*")
{
write-host "Powershel 7 continue"
Write-Host "Before Start-session"
$s = New-PSSession -HostName ip -UserName user -verbose -KeyFilePath C:\.ssh\id_rsa
Write-Host "After Start-session"
}else{
Start-Process pwsh.exe -Wait -PassThru -ArgumentList "-NonInteractive -ExecutionPolicy Bypass -File $($MyInvocation.MyCommand.Definition)"
}
stop-transcript
My Problem is that Write-Host "After Start-session" is never reached.
The first Start-Transcript shows, that the Script is started again with pwsh.exe
The second Start-Transcript shows the Output till Before Start-session.
After that there is nothing added to the Transcript and the Process keeps running.
The Script is working fine, when it is running under the Administrator Account.
How can I debug this ?
The Problem was that the SSH fingerprint was not trusted.
When I runned the Script via a command Line instead of via Jenkins direct, i got this output:
The authenticity of host 'ip (ip)' can't be established.
ECDSA key fingerprint is SHA256:gQv8WE8G04RhfNNX7pRQjVX0lPj3jNZ4JTPIDNEIGHk.
Are you sure you want to continue connecting (yes/no)?
After i answered it with yes everything worked.
The Jenkings Job is now working two.
Running the following lines of PowerShell code (on a WIN 2008 R2 server, with administrator rights):
try {
Import-Module webadministration -ErrorAction Stop
}
catch {
"ERROR : $( $Error[ 0 ].ToString() )"
}
Will throw an error onto the console, and will not actually pass it to the catch block:
Process should have elevated status to access iis configuration data
The above error is displayed as is except the color is red on the PowerShell console. To be clear - There is no other text being displayed except for the above Error. The $Error[ 0 ] is not populated as well.
It almost seems like the Error did not generate from the PowerShell script, but from an external process/script.
Is there any way to suppress this error? Even after supplying the ErrorAction preference in the try-catch block, the error still displays.
Additionally, The following will NOT work:
Import-Module webadministration -ErrorAction Stop
Import-Module webadministration | Out-Null
Import-Module webadministration 2>&1 | Out-Null
$null = Import-Module webadministration
Import-Module webadministration -ErrorAction SilentlyContinue
$ErrorActionPreference = 'SilentlyContinue'
Import-Module webadministration
Of note, the Import-Module webadministration command works after loading the second time in the same PowerShell session! Meaning,
# First Go
Import-Module webadministration
# error thrown on first go
# Second Go
Import-Module webadministraion
# Second go works! It loads the 'webadministration' module
I'm trying to create a PowerShell script (loop) for periodical checking if some other PowerShell script with specific command is running. If not I start it.
This is what I have:
$processInfo = Get-WmiObject Win32_Process -Filter "name = 'powershell.exe'" | select CommandLine | Out-String -width 200
while($true) {
if ($processInfo -NotLike '*specific_path*') {
Write-Host 'process not running'
Start-Process powershell -argument '-f X:\specific_path\other_script.ps1'
}
else { Write-Host 'process is running' }
Start-Sleep -Seconds 60
}
The script correctly detects running or not running process when started. but when situation changes during the script run, it does not detect it.
Also, when script starts, detects that the other script is not running, it starts it correctly but then it does not see it already running and starts it again and again.
So the only problem I have (I believe) is how to get "fresh" data about running processes. Any ideas? Many thanks!
I would like to install a set of applications: .NET 4, IIS 7 PowerShell snap-ins, ASP.NET MVC 3, etc. How do I get the applications to install and return a value that determines if the installation was successful or not?
These answers all seem either overly complicated or not complete enough. Running an installer in the PowerShell console has a few problems. An MSI is run in the Windows subsystem, so you can't just invoke them (Invoke-Expression or &). Some people claim to get those commands to work by piping to Out-Null or Out-Host, but I have not observed that to work.
The method that works for me is Start-Process with the silent installation parameters to msiexec.
$list =
#(
"/I `"$msi`"", # Install this MSI
"/QN", # Quietly, without a UI
"/L*V `"$ENV:TEMP\$name.log`"" # Verbose output to this log
)
Start-Process -FilePath "msiexec" -ArgumentList $list -Wait
You can get the exit code from the Start-Process command and inspect it for pass/fail values. (and here is the exit code reference)
$p = Start-Process -FilePath "msiexec" -ArgumentList $list -Wait -PassThru
if($p.ExitCode -ne 0)
{
throw "Installation process returned error code: $($p.ExitCode)"
}
Depends. MSIs can be installed using WMI. For exes and other methods, you can use Start-Process and check the Process ExitCode.
msi's can also be installed using msiexec.exe, msu's can be installed using wusa.exe, both have a /quiet switch, /norestart and /forcerestart switches and a /log option for logging (specify the file name).
You can read more about the options if you call them with /?
Note: wusa fails silently when they fail, so you have to check the log file or eventlog to determine success.
I have implemented exactly what you are looking for at my current project. We need to automate deployment and instillation of n number of apps across multiple environments and datacenters. These scripts are slightly modified from the original version for simplicity sake since my complete code is reaching 1000 lines but the core functionality is intact. I hope this does what you are asking for.
This PS function pulls all the apps from the registry (what add/remove programs reads from) and then search's for the supplied app name and display version. In my code (PSM1) I run this function before I install to whether or not it is their and then afterword’s to verify that it got installed…. All this can be wrapped in one master function to manager flow control.
function Confirm-AppInstall{
param($AppName,$AppVersion)
$Apps = Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*|?{$_.DisplayName -ne $Null}|?{$_.DisplayName -ne ""}
$Apps += Get-ItemProperty Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*|?{$_.DisplayName -ne $Null}|?{$_.DisplayName -ne ""}
$Installed = $Apps|?{$_.DisplayName -eq ""}|?{$_.DisplayVersion -eq ""}|select -First 1
if($Installed -ne $null){return $true}else{return $false}
}
This PS function will load a txt file that has the install commands prepopulated (one command per line). and run each line indivaduly and wait for the install to complete before moving on to the next.
function Install-Application{
param($InstallList = "C:\Install_Apps_CMDS.txt")
$list = gc -Path $InstallList
foreach ($Command in $list){
Write-Output ("[{0}]{1}" -f (Get-Date -Format G),$call)
#Make install process wait for exit before continuing.
$p = [diagnostics.process]::Start("powershell.exe","-NoProfile -NoLogo -Command $Command")
$p.WaitForExit()
Start-Sleep -Seconds 2
#Searches for the installer exe or msi that was directly opened by powershell and gets the process id.
$ProcessID = (gwmi -Query ("select ProcessId from Win32_Process WHERE ParentProcessID = {0} AND Name = '{1}'" -f $p.Id,$ParentProcessFile)|select ProcessId).ProcessId
#waits for the exe or msi to finish installing
while ( (Get-Process -Id $ProcessID -ea 0) -ne $null){
Start-Sleep -Seconds 2
$ElapsedTime = [int](New-TimeSpan -Start $P.StartTime -End (Get-Date)|select TotalSeconds).TotalSeconds
#install times out after 1000 seconds so it dosent just sit their forever this can be changed
if(2000 -lt $ElapsedTime){
Write-Output ('[{0}] The application "{1}" timed out during instilation and was forcfully exited after {2} seconds.' -f (Get-Date -Format G),$App.Name,(([int]$App.InstallTimeOut) * 60))
break
}
}
#clean up any old or hung install proccess that should not be running at this point.
Stop-Process -Name $ParentProcessName -ea 0 -Force
Stop-Process -Name msiexec -ea 0 -Force
}
}
The TXT file should be formatted as such... you will need to do you research on how to each app needs to be installed. a good resource is appdeploy.com
C:\Install.exe /q
C:\install.msi /qn TRANSFORMS='C:\transform.mst'
C:\install2.msi /qn /norestart
C:\install3.exe /quiet
Let me know if there are any errors I had to modify my existing code to remove the proprietary values and make this a little more simplistic. I am pulling my values from a custom XML answer sheet. But this code should work as I have supplied it.
If you would like for me to discuss more about my implementation let me know and i can make a more detailed explanation and also add more of the supporting functions that I have implemented.