powershell script - different behavior after start with windows scheduler - powershell

I have this script to check if there is mapped disk on remote server. When I run it in command line, it works perfectly, from PowerGUI and ISE it works perfectly, but when I shedule it in Windows task scheduler, I get a mail message (mail sending part of script is not included), that disk is not mapped - the "else" is executed in spite of disk is mapped.
if(Invoke-Command -ComputerName sdebt -ScriptBlock { Get-WmiObject win32_logicaldisk -ComputerName sdebt -Filter "DeviceID = 'L:'"}) {
Write-Host -ForegroundColor Green "L: is OK"} else {
Write-Host -ForegroundColor Magenta "L: is NOT OK"
$subject = "CHYBA: Disk L is not mapped"
$body += "Disk L is not mapped `r" }
Thank you.

Probably is related with permissions.
When you run it from your commandline/ISE/PowerGUI you are using your credentials
When you run it from schedule task by default you run it with system credentials
If I were you I would:
Try running it with your credentials to see if this make a difference.
Try running it with highest privileges
If after 1) and 2) still fails at least you know for sure that is not a permission issue :-)

Related

Double hop issue from appserver to sqlinstance

We have released a change that makes a windows console application authenticate with an ad-user (trusted connection = yes) instead of sql-user.
This has caused problems starting the application from System Center Orchestrator via Powershell due to double jump issues.
Orchestrator -> Appserver -> SQLServer
Powershell from Orchestrator:
Invoke-Command -ComputerName Appserver -ScriptBlock {
cd 'D:\Program Files\Application\'
.\Application.exe }
Errormsg:
"Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. 'SELECT * FROM Globals"
The aduser running the script is local admin on all three servers and sa on the sql-instance.
The solution I tested, that works when double jumping between SQL servers, is to set attributes msDS-AllowedToDelegateTo and UserAccountControl.
Set-adcomputer -Identity Appserver -Add #{'msDS-AllowedToDelegateTo'=#(
'MSSQLSvc/SQLServer.Domain.local',
'MSSQLSvc/SQLServer.Domain.local:1433',
'MSSQLSvc/SQLServer.Domain.local:INSTANCENAME'
)}
Set-adcomputer -Identity Appserver -Replace #{UserAccountControl= 4096}
This however does not make a difference in this case.
Does anyone know a solution to this problem?

Powershell script to run parallel on different server to perform cleanup

I want to perform disk cleanup on 500 VDIs using below script and create a proper report with VDI status(online or offline) and disk space detail using below script .But here Iam not using for each loop as I want to run cleanup parallel on VDIs .If any VDI is offline or winRM not enabled the script will throw error for that VDIs ,I want to catch those VDI and put in report if they are offline or any other winrm error .I can get disk space detail for online VDI but how to get offline or error VDI status in report ???????
$AllVDI = get-content "list for500 vDI "
$Space= Invoke-Command -ComputerName $AllVDI -ScriptBlock {
Remove-Item -Path "C:\Windows\Temp\*" -Recurse -Force
Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
}
$Space|select systemname,drive,freespace|export.csv "C:\report"
Hi Actually I am using PowerShell 5.1 so cannot use foreach-object -Parallel
invoke-command -computername srv1,srv2,srv3 -scriptblock {get-process}
This command by default will run in parallel .I just wanted proper report with offline and online servers with disk space detail . I got my issue resolved from Microsoft QnA ..Just FYI the below link the way I m expecting .
Thank you for your help indeed ...appreciated
https://learn.microsoft.com/en-us/answers/questions/230721/powershelll-script-to-get-server-status-and-disk-s.html?childToView=231124#answer-231124

How to start a process on remote computer using powershell WMI?

We are upgrading our servers and need to stop our application before we perform update and then start it back again.
I was reading online about this and most of the links talk about remoting but some of the machines don't have PSRemoting enabled and therefore I need to stick to using wmi.
Would appreciate some pointers on this ?
To terminate the process I am using something like below:
$processes=Get-WmiObject -Class Win32_Process -ComputerName $Address -Filter "name='$ProcessName'"
foreach ($process in $processes)
{
$returnval = $process.terminate()
$processid = $process.handle
if($returnval.returnvalue -eq 0) {
write-host "The process $ProcessName `($processid`) terminated successfully"
}
else {
write-host "The process $ProcessName `($processid`) termination has some problems"
}
}
You don't say what OS and PS version(s) you are trying to deal with.
You are not saying what or if you are having issues with what you posted.
Even using only WMI, you still must have Windows WMI properly configured to do this as well as know Windows is not out of the boxed configured to let you what you are after without making all the proper WinRM, WMI and firewall manual configs.
It's far simpler just to enable PSRemoting via GPO.
Otherwise, you will need tp look toward maybe winrs.exe or MS SysInternals psexec.
winrs
Windows remote Management allows you to manage and execute programs remotely.
PsExec v2.2
Also back to my what OS and PowerShell version you are using. There is the
Invoke-Wmi​Method
Which can lead to stuff like this ---
Invoke-WmiMethod -ComputerName $TargetMachine -Namespace root\cimv2 -Class Win32_Process..."

Determining when machine is in good state for Powershell Remoting?

Update - the original question claimed that I was able to successfully perform an Invoke-Command and then shortly after was unable to; I thought it was due to processes going on during login after a windows upgrade.
It turns out the PC was actually starting, running a quick batch/cmd file, and then restarting. This is what was leading to being able to do PS Remoting and then suddenly not. The restart was quick enough after first boot that I didn't realize it was happening. Sorry for the bad question.
For the curious, the machine was restarting because of a remnant of the Microsoft Deployment Toolkit in-place upgrade process. The way MDT completes its task-sequence post-upgrade is problematic for many reasons, and now I've got another to count.
Old details (no longer relevant, with incorrect assumption that machine was not restarting after first successful Invoke-Command):
I'm automating various things with VMs in Hyper-V using powershell and powershell remoting. I'll start up a VM and then want to run some commands on it via powershell.
I'm struggling with determining when I can safely start running the remote commands via things like Invoke-Command. I can't start immediately as I need to let the machine start up.
Right now I poll the VM with a one second sleep between calls until the following function returns $true:
function VMIsReady {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)][object]$VM
)
$heartbeat = $vm.Heartbeat
Write-Host "vm heartbeat is $heartbeat"
if (($heartbeat -eq 'OkApplicationsHealthy') -or ($heartbeat -eq 'OkApplicationsUnknown'))
{
try
{
Invoke-Command -VMName $vm.Name -Credential $(GetVMCredentials) {$env:computername} | out-null
}
catch [System.Management.Automation.RuntimeException]
{
Write-Host 'Caught expected automation runtime exception'
return $false
}
Write-Host 'remoting ready'
return $true
}
}
This usually works well; however, after a windows upgrade has happened, there are issues. I'll get Hyper-V remoting errors of various sorts even after VMIsReady returns $true.
These errors are happening while the VM is in the process of first user login after upgrade (Windows going through "Hi;We've got some updates for your PC;This might take several minutes-Don't turn off your PC). VMIsReady returns true right as this sequence starts - I imagine I probably should be waiting until the sequence is done, but I've no idea how to know when that is.
Is there a better way of determining when the machine is in a state where I can expect remoting to work without issue? Perhaps a way to tell when a user is fully logged on?
You can use Test-WSMan.
Of run a script on the invoke that will receive a response from the server.
[bool]$Response | Out-Null
try{
$Response = Invoke-Command -ComputerName Test-Computer -ScriptBlock {return $true}
}catch{
return $false
}
if ($Response -ne $true){
return $false
}else{
return $true
}

Trying to create process on remote PC from network share

I have this Powershell:
Try
{
#Start the installer remotely
$process = ([WMICLASS]"\\$comp\ROOT\CIMV2:Win32_Process").Create($InstallString)
if ( $process.ReturnValue -eq 0 )
{
$logstr = $comp + ": spawned process " + $process.ProcessId
Write-Host -ForegroundColor GREEN $logstr
}
else
{
Write-Host -ForegroundColor RED "${comp}: failed to create process ${InstallString}"
Continue
}
}
Catch
{
Write-Host -ForegroundColor RED "${comp}: error: $_.Exception.Message"
Continue
}
Where $comp is a valid PC name and InstallString is \\SERVERNAME\ShareFolder\setup.exe.
Within that ShareFolder is an installer and its files. I expect I can run the setup like this to remote install, but it is not working. It's falling into the else:
COMPUTERNAME: failed to create process \\SERVERNAME\ShareFolder\setup.exe
What am I missing? I can access this path outside Powershell.
This works on a local path. Do I need some special syntax in Powershell to point to this share?
This code works if the exe (well, a different installer) is located on COMPUTERNAME and the code is still executed remotely.
It could be a permission problem. According to this link: Creating Processes Remotely
A process created remotely can run under any account if the account has the Execute Method and Remote Enable permissions for root\cimv2. The Execute Method and Remote Enable permissions are set in WMI Control in the Control Panel.