using this script getting error to run MSI file - powershell

#===VARIABLES===##
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition # Gets the current directory
$TempPath=$env:temp
$Installer="$ScriptPath\Workstation.msi" # MSI name
# Use for new installs and upgrades. DO NOT CHANGE!!
$ArgumentList = " /i /quiet" # Standard arguments
##===LOGGING===##
Start-Transcript -Path "$($env:ProgramData)\WEIntune\AdminByRequest.log" -Append # Generate log
Write-Host "Starting script:" $(Get-Date -format 'MM/dd/yy HH:mm:ss')
##===INSTALL MSI===##
Write-Host "Installation Start Time:" $(Get-Date -format 'MM/dd/yy HH:mm')
Write-Host "Source Files:"$ScriptPath
$InstallTime = Measure-Command {start-process $Installer -wait -argumentlist $ArgumentList} # Call setup with argument & measure install time
$FinalInstallTime=[math]::Round($InstallTime.TotalMinutes,2) # Cleanup time format
EXIT 0 # Exit with Return Code 0
please help to run this scipt ,wanted to install MSI file

Related

Passing switch when calling other script

I am taking over a process (originally created by a vendor) that creates and configures a VM. The process can either create a VM in hyperv on a physical host, or in vsphere. This is a powershell script called migrate-storeservers.ps1.
As part of the configuration, migrate-storeservers.ps1 calls a script locally on the VM that performs database validation (Validate-StoreServerDB.ps1). In the event that the VM is created in vsphere, we only want certain validation tasks to run.
I added a vsphere switch to the Migrate-StoreServers.ps1, and added logic to the function that calls the database validation script.
Vsphere switch at top of script:
[cmdletbinding()]
Param (
[Parameter(Mandatory=$true)]$Store,
[switch]$FinalizeVm,
[switch]$Vsphere,
[switch]$SqlSafe,
[switch]$FullAuto,
[switch]$TestRun,
$ErrorActionPreference = "Stop"
)
Function that calls database validation script, where $taskArgs are set based on Vsphere switch being used or not:
function validateDatabase($newServer, $newVmSession, $validateScript, $userScript, $moduleFile, $outLog){
$global:currentTask = "Database Validation"
Write-Debug "Current Task: $global:CurrentTask"
Write-Host "Starting database validation on server: $newServer"
$startTime = Get-Date
Write-Host "Start time: $startTime" -ForegroundColor Green
stageAaronsLiteModule -inModuleFile $moduleFile -inSession $newVmSession
$dateString = Get-Date -Format "yyyyMMddTHHmmss"
$logName = $("DBValidate_" + $newServer.ToUpper() + "_" + $dateString + ".log")
if($Vsphere){
$taskArg = "-NoProfile -ExecutionPolicy Unrestricted -File {0} -Store {1} -LogPath {2} -LogFile {3} -Vsphere {4}" `
-f $validateScript, $newServer, $outLog, $logName, $Vsphere
} else{
$taskArg = "-NoProfile -ExecutionPolicy Unrestricted -File {0} -Store {1} -LogPath {2} -LogFile {3}" `
-f $validateScript, $newServer, $outLog, $logName
}
executeTask -inTaskName "DatabaseValidation" -inPsSession $newVmSession -inUserScript $userScript -inTaskArg $taskArg `
-inMessage "Database Validation Script is starting. This takes about 2 minutes" -inCred $cred
Start-Sleep -Seconds 5
$logFound = copyLogToSource -inServer $newServer -inLog $($outLog + "\" + $logName) -outLogPath $LocalLogPath
if(-not($logFound)){
exitScript -inMessage "ERROR: Unable to find/copy log file" -failed $true
}
Start-Sleep 5
parseLogForErrors -inLog $($LocalLogPath + "\" + $logName) -errorString "TerminatingError"
$endTime = (Get-Date) - $startTime
Write-Host "Validate Database completed in: $endTime" -ForegroundColor Green
}
In the validation script being called by the function I added a vsphere switch and logic that sets the tasks list based on if the vsphere switch is used.
[cmdletbinding()]
Param (
[Parameter(Mandatory=$true)]$Store,
[Parameter(Mandatory=$true)]$LogPath,
[Parameter(Mandatory=$true)]$LogFile,
[switch]$Vsphere,
$ErrorActionPreference = "Stop"
)
########### Start Global Variable Section ###########
$sqlInstance = ($Store.ToUpper() + "\POS")
$sqlDatabase = "master"
$sqlConnectionTimeout = 60
$sqlQueryTimeout = 240
if($Vsphere){
$tasks = #(
"GoNoGo_Store2016_Upgrade_10_CheckServerName",
"GoNoGo_Store2016_Upgrade_20_CheckSQLVersion",
"GoNoGo_Store2016_Upgrade_30_CheckDBOnline",
"GoNoGo_Store2016_Upgrade_50_CheckDBExists"
)
} else{
$tasks = #(
"GoNoGo_Store2016_Upgrade_10_CheckServerName",
"GoNoGo_Store2016_Upgrade_20_CheckSQLVersion",
"GoNoGo_Store2016_Upgrade_30_CheckDBOnline",
"GoNoGo_Store2016_Upgrade_40_CheckSysMergeArcticles",
"GoNoGo_Store2016_Upgrade_50_CheckDBExists",
"GoNoGo_Store2016_Upgrade_60_CheckReplicationStatus"
)
}
My question is does the logic in the migrate-storeservers.ps1 look like it will pass the vsphere switch correctly to the validate-storeserverdb.ps1?
I am rather new to more advanced powershell like this and am concerned that the $taskArg for when the Vsphere switch is used are maybe not formatted correctly to pass the vsphere switch. The $taskArg for if the switch is not used was how the script was formatted before I added the switch logic.
Any input will be greatly appreciated.

Powershell will not start or stop Windows service with nssm

i have a script made in powershell and i am using nssm to create as a service to be executed every "x" time, however when starting the service it generates error and does not execute.
I have full administrator rights and I even tried to run PowerShell as an administrator without success.
If I run the script directly it works, however using nssm it is not working.
The error that happens is this:
Start-Service: Service 'nice (nice)' start failed.
At C: \ Program Files \ NICE Systems \ nssm.ps1: 10 char: 14
Start-Service <<<< $ serviceName
CategoryInfo: OpenError: (System.ServiceProcess.ServiceController: ServiceController) [Start-Service],
ServiceCommandException
FullyQualifiedErrorId: StartServiceFailed, Microsoft.PowerShell.Commands.StartServiceCommand
nssm.ps1
$nssm = (Get-Command nssm.exe).Definition
$serviceName = 'nice'
$powershell = (Get-Command powershell.exe).Definition
$scriptPath = 'C:\Program Files\NICE Systems\script_delecao.ps1'
$arguments = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $scriptPath
& $nssm install $serviceName $powershell $arguments
& $nssm status $serviceName
Start-Service $serviceName
Get-Service $serviceName
script_delecao.ps1
$logPath = "C:\Program Files\NICE Systems\Logs\*\Archive\*"
# -------------------------------------------------------------------------------------------
# SET $NDAYS WITH THE NUMBER OF DAYS TO KEEP IN LOG FOLDER.
$nDays = 180
# -------------------------------------------------------------------------------------------
# SET $EXTENSIONS WITH THE FILE EXTENSION TO DELETE.
# YOU CAN COMBINE MORE THAN ONE EXTENSION: "*.LOG, *.TXT,"
$Extensions = "*.log*"
# -------------------------------------------------------------------------------------------
# PAY ATTENTION! IF YOU COMBINE MORE THAN ONE LOG PATH AND EXTENSIONS,
# MAKE SURE THAT YOU ARE NOT REMOVING FILES THAT CANNOT BE DELETED
# -------------------------------------------------------------------------------------------
$PathDelete = "C:\Program Files\NICE Systems\Delecoes"
while ($true) {
If(!(test-path $PathDelete))
{
New-Item -ItemType Directory -Force -Path $PathDelete
}
$LogDate = (Get-Date).ToString("dd_MM_yyyy")
$DateTime = (Get-Date).ToString("yyy-MM-ddThh:mm:ss")
$Files = Get-Childitem $LogPath -Include $Extensions -Recurse | Where `
{$_.LastWriteTime -le (Get-Date).AddDays(-$nDays)}
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
$Log = $DateTime + " - O arquivo " + $File + " foi deletado "
$Log | Out-File -Append $PathDelete\DeleteLogFile_$LogDate.log
Remove-Item $File.FullName| out-null
}
}
# Add a sleep at the end of the loop to prevent the script from eating
# too much CPU time
$Log = $DateTime + " FINAL DO ARQUIVO "
$Log | Out-File -Append $PathDelete\DeleteLogFile_$LogDate.log
Start-Sleep -Seconds 300
}
I believe I have a similar scenario where I cannot back-up Bamboo file system while it's running. My back-up executes from a rundeck server via Remote PowerShell, and even though the user has local admin rights it cannot stop and start services using NSSM. So I use this function to run the command elevated
ELEVAT "nssm stop bamboo"
tar --exclude=./logs --exclude=./temp --exclude=*.log --exclude=*.jar --verbose -czf E:\dropfolder\bamboo-home.tar.gz --directory=E:\bamboo-home .
ELEVAT "nssm start bamboo"
the function itself...
function ELEVAT ($command) {
$scriptBlock = [scriptblock]::Create($command)
configuration elevated {
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
Set-StrictMode -Off
Node localhost {
Script execute {
SetScript = $scriptBlock
TestScript = {
if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Verbose "Verified Elevated Session"
return $false
} else {
Write-Verbose "Not an Elevated Session!"
exit 9996
}
}
GetScript = { return #{ 'Result' = 'RUN' } }
}
}
}
$mof = elevated
Start-DscConfiguration ./elevated -Wait -Verbose -Force
if ( $error ) { Write-Host "[ELEVAT][WARN] `$Error[] = $Error" ; $Error.clear()
}
}

Powershell: Call Debug Analyzer cdb.exe as Process

i need to call the cdb.exe as a Process to check to kill the process after a few seconds.
Some Dumps cannot be analyzed so i have to do an other call.
Here you can see my code. But it doesn't work. The cdb.exe is not started correctly and i am not getting the output file.
Do you have some advises for me?
The call "before" implementing the process part starts the cdb.exe
$maximumRuntimeSeconds = 3
$path = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"
$process = Start-Process -FilePath $path "-z $unzippedFile.FullName, -c `".symfix;.reload;!analyze -v; q`""
try {
$process | Wait-Process -Timeout $maximumRuntimeSeconds -ErrorAction Stop > $outputFile
Write-Warning -Message 'Process successfully completed within timeout.'
}
catch {
Write-Warning -Message 'Process exceeded timeout, will be killed now.'
$process | Stop-Process -Force
}
# call before implementing Process
& "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe" -z $unzippedFile.FullName -c ".symfix;.reload;!analyze -v; q" > $outputFile
-Passthru was needed to make Wait-Process work.
I think you also need to look at how the double quoted string is expanding. I think $UnzippedFIle.Fullname might be adding a literal ".FullName" at the end of the actual fullname of the zip file. I don't have your environment, but the rudementary tests I've done show that. Try packing it in a sub-expression like:
"-z $($unzippedFile.FullName), -c `".symfix;.reload;!analyze -v; q`""
Let me know how that goes. Thanks.
C:\>dir /b ok.txt
File Not Found
C:\>type dodump.ps1
$path = "C:\Program Files\Windows Kits\10\Debuggers\x86\cdb.exe"
$process = Start-Process -PassThru -FilePath $path -ArgumentList "-z `"C:\calc.DMP`"" ,
"-c `".symfix;.reload;!analyze -v;q`"" -RedirectStandardOutput c:\\ok.txt
try {
$process | Wait-Process -Timeout 100 -ErrorAction Stop
Write-Host "Process finished within timeout"
}catch {
$process | Stop-Process
Write-Host "process killed"
}
Get-Content C:\ok.txt |Measure-Object -Line
C:\>powershell -f dodump.ps1
Process finished within timeout
Lines Words Characters Property
139

Calling other PowerShell scripts within a PowerShell script

I'm trying to get one master PowerShell script to run all of the others while waiting 30-60 seconds to ensure that the tasks are completed. Everything else I tried wouldn't stop/wait for the first script and its processes to complete before going through all the others at the same time and would cause a restart automatically.
Main script, run as admin:
$LogStart = 'Log '
$LogDate = Get-Date -Format "dd-MM-yyy-hh-mm-ss"
$FileName = $LogStart + $LogDate + '.txt.'
$scriptList = #(
'C:\Scripts\1-OneDriveUninstall.ps1'
'C:\Scripts\2-ComputerRename.ps1'
);
Start-Transcript -Path "C:\Scripts\$FileName"
foreach ($script in $scriptList) {
Start-Process -FilePath "$PSHOME\powershell.exe" -ArgumentList "-Command '& $script'"
Write-Output "The $script is running."
Start-Sleep -Seconds 30
}
Write-Output "Scripts have completed. Computer will restart in 10 seconds."
Start-Sleep -Seconds 10
Stop-Transcript
C:\Scripts\3-Restart.ps1
1-OneDriveUninstall.ps1:
Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0
taskkill /f /im OneDrive.exe
C:\Windows\SysWOW64\OneDriveSetup.exe /uninstall
2-ComputerRename.ps1:
$computername = Get-Content env:computername
$servicetag = Get-WmiObject Win32_Bios |
Select-Object -ExpandProperty SerialNumber
if ($computername -ne $servicetag) {
Write-Host "Renaming computer to $servicetag..."
Rename-Computer -NewName $servicetag
} else {
Write-Host "Computer name is already set to service tag."
}
The log file shows:
Transcript started, output file is C:\Scripts\Log 13-09-2019-04-28-47.txt.
The C:\Scripts\1-OneDriveUninstall.ps1 is running.
The C:\Scripts\2-ComputerRename.ps1 is running.
Scripts have completed. Computer will restart in 10 seconds.
Windows PowerShell transcript end
End time: 20190913162957
They aren't running correctly at all though. They run fine individually but not when put into one master script.
PowerShell can run PowerShell scripts from other PowerShell scripts directly. The only time you need Start-Process for that is when you want to run the called script with elevated privileges (which isn't necessary here, since your parent script is already running elevated).
This should suffice:
foreach ($script in $scriptList) {
& $script
}
The above code will run the scripts sequentially (i.e. start the next script only after the previous one terminated). If you want to run the scripts in parallel, the canonical way is to use background jobs:
$jobs = foreach ($script in $scriptList) {
Start-Job -ScriptBlock { & $using:script }
}
$jobs | Wait-Job | Receive-Job

Executing XMLA with AMO PowerShell does not create measures

I wrote a PowerShell script to automate deployment of SSAS Cubes. I use the Deployment Wizard to generate an XMLA file and then PowerShell AMO command to deploy it. However, when I run it the tabular database gets created but all measures are missing. Running the same XMLA from SQL Management Studio or using Invoke-ASCmd produce the correct database with all measures in it. Am I missing an option or something in the "Invoke" command?
[CmdletBinding()]
Param(
# InputDir is required
[Parameter(Mandatory=$True,Position=1)]
[string]$InputDir,
# Server is optional
[Parameter(Mandatory=$False,Position=2)]
[string]$Server=$env:computername
)
# Output execution parameters.
"Executing with the following parameters:"
" InputDir: $InputDir"
" AS Database Server: $Server`n"
$XmlaDir = Resolve-Path($InputDir)
$Xmla = Join-Path -Path $XmlaDir -ChildPath '\Model.xmla'
$ASFiles = Get-ChildItem -Recurse -Path $InputDir -Filter *.asdatabase
$Count = $ASFiles.Count
If($Count -ne 1)
{
Write-Host("`ERROR: Count asdatabase file(s) found at $inputdir")
Exit 1
}
$ASDatabase = $ASFiles[0].FullName
Write-Host("`nUsing $ASDatabase for deployment.")
Write-Host("`nAttempting to create $Xmla ...`n")
# Use Analysis Services Deployment Utility to generate XMLA file from
.asdatabase file
$Script:ASDeployWizard = "E:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Microsoft.AnalysisServices.Deployment.exe
"
$Arguments = #("`"$ASDatabase`"", "/s", "/o:`"$Xmla`"")
Start-Process -FilePath $Script:ASDeployWizard -ArgumentList $Arguments -Wait
If ((-Not $?) -Or -Not (Test-Path $Xmla))
{
"Cannot generate deployment descriptor. Deployment aborted."
Exit 1
}
Write-Host("XMLA deployment descriptor generated.`n")
Try {
Import-Module SQLPS -DisableNameChecking
# Deploy Cube
"Invoking deployment script. This may take several minutes...`n"
$AS = New-Object Microsoft.AnalysisServices.Server
$AS.connect($Server)
$CubeDescriptor = [string](Get-Content $Xmla)
$Results = $AS.Execute($CubeDescriptor)
Foreach ($r in $Results) {
$r.Messages.Description
}
"Done.`n"
} Catch {
Write-Host($_.Exception.GetType().FullName + "`n" + $_.Exception.Message + "`n")
Write-Host("Deployment FAILED.`n")
}
Exit 0