powershell invoke-command does not work if I use -computerName - powershell

I want to execute below code in the either local or remote machine whith current user.
$BackUpSqlAgentAndRemoveOldbackup = {
param([string]$AppServer,[string]$SqlInstance,[string]$BackupShare,[string]$alias)
[Environment]::UserName #I got same user name in all cases.
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') | Out-Null
$server = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $SqlInstance
$backupName = 'SqlAgentJob_' + $SqlInstance + '_' + (Get-Date –format ‘yyyyMMdd_HHmm’) + '_' + $alias + '.sql'
$backupPath = join-path $BackupShare $backupName
$oldBackups = Get-ChildItem $backupShare | where { ( $_.name -like 'SqlAgentJob_*.sql' ) }
$server.JobServer.Jobs.Script() | Out-File -filepath $backupPath
foreach ( $item in $oldBackups ) { remove-item $item.fullName }
}
the #argList is
#('hafcapp-1', 'hafcsql-1', '\\Host5FileSrv\Backup\test','auto')
I notice that
this one, it works well (no -comupterName and -session)
Invoke-Command -ScriptBlock $BackUpSqlAgentAndRemoveOldbackup -argumentList $argList
this one, it throw execption (I also tried "-session", get same result)
Invoke-Command -computerName localhost -ScriptBlock $BackUpSqlAgentAndRemoveOldbackup -argumentList $argList
the exception is as below, it seems the it can not access the folder.
Cannot find path '\\Host5FileSrv\Backup\test' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\Host5FileSrv\Backup\test:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (Script:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Cannot bind argument to parameter 'Path' because it is null.
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand
does anyone know how can I do if I want to add computerName or session?
(notes:[Environment]::UserName return identical user)

You have run into the double hop problem. Your credentials can be transferred to the next machine (first hop), but no further (second hop). This means that you can't use the credentials of the machine where you are executing Invoke-Command on, the remote machine (localhost) to connect to a file share (\Host5FileSrv\Backup). Even if you use localhost as computername, it is still remoting. A solution could be CredSSP. See here and here for more information.

This looks like a "second hop" remoting problem, and you'll need to configure WinRM on the computers involved to use CredSSP
http://msdn.microsoft.com/en-us/library/windows/desktop/ee309365(v=vs.85).aspx

Related

Powershell class inside script block for Invoke-Command

I've faced up with a problem to execute powershell class methods inside a scriptblock passed to invoke-command.
Let's start with some examples
FooClass.psm1
class Foo {
static [string]Func() {
return "bar"
}
}
FooToScriptblock.ps1
using module .\FooClass.psm1
Function FooToScriptBlock {
$m = [Foo]::new()
write-host "from func:" $m.Func()
$sb1 = {$m = [Foo]::new(); $m.Func()}
$sb2 = {param($foo)$foo.Func()}
$sb3 = [scriptblock]::Create('$m.Foo()')
$s = New-PSSession -ComputerName "computer" -Credential "someuser"
$r1 = Invoke-Command -Session $s -ScriptBlock $sb1
write-host $r1
$r2 = Invoke-Command -Session $s -ScriptBlock $sb2 -ArgumentList $m
write-host $r2
$r3 = Invoke-Command -Session $s -ScriptBlock $sb3
write-host $r3
}
FooToScriptBlock
After executing I'm getting output like this
PS <scripts> $> .\FooToScriptblock.ps1
from func: bar
Unable to find type [Foo].
+ CategoryInfo : InvalidOperation: (Foo:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
+ PSComputerName :
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
+ PSComputerName :
Method invocation failed because [Deserialized.Foo] does not contain a method named 'Func'.
+ CategoryInfo : InvalidOperation: (Func:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
+ PSComputerName :
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
+ PSComputerName :
So now the question. Is it possible to execute PowerShell classes inside a script block on another computer?
The easiest solution is to specify the 'Using' statement in the PSSession by adding something like the following.
$sb = {using module UNC_Path_to_Module\FooClass.psm1}
$r = Invoke-Command -Session $s -ScriptBlock $sb
It should be noted that since PSSessions do not pass credentials to remote session by default and will not allow access to network resources requiring authentication. In order to authenticate to network resources you will need to specify the authentication method as CredSSP. This carries a security risk if the remote system is compromised.
New-PSSession -Authentication CredSSP

I am trying to automate adding mailbox permission with variables

I am trying to run this script to add permissions to mailboxes. If I remove all of the variables it works fine .. but I really need to be able to automate this. the code is not accepting the values I have assigned to each of the variables. guessing it ahs something to do with that the code is using a variable inside another one.
$MB = MAILBOX
$GR = GROUP
$PR = PERMISION
ForEach($f in (Get-MailboxFolderStatistics $MB | Where { $_.FolderPath.Contains("/") -eq $True } ) )
{
$fname = '$MB:' + $f.FolderPath.Replace("/","\"); add-MailboxFolderPermission $fname -User $GR -AccessRights $PR
Invoke-Command $fname
Start-Sleep -Milliseconds 1000
}
$MB Errors
The specified mailbox "$MB" doesn't exist.
+ CategoryInfo : NotSpecified: (:) [Add-MailboxFolderPermission], ManagementObjectNotFoundException
+ FullyQualifiedErrorId : [Server=xxxxxxxx,RequestId=xxxxxxx,TimeStamp=5/31/2019
9:50:08 PM] [FailureCategory=Cmdlet-ManagementObjectNotFoundException] CCB4481D,Microsoft.Exchange.Management.Sto
reTasks.AddMailboxFolderPermission
$GR Errors
Cannot bind argument to parameter 'User' because it is null.
+ CategoryInfo : InvalidData: (:) [Add-MailboxFolderPermission], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Add-MailboxFolderPermission
Any help pointing me in the right direction would be a huge help.
Thanks

'Provider load failure' during installation process

I execute two Powershell scripts during a installation process from a desktop application under Windows 10 IoT Enterprise.
%WINDIR%\System32\WindowsPowerShell\v1.0\PowerShell.exe -ExecutionPolicy Bypass -File ".\KeyboardFilter.ps1"
%WINDIR%\System32\WindowsPowerShell\v1.0\PowerShell.exe -ExecutionPolicy Bypass -File ".\ShellLauncher.ps1"
But the execution of the Powershell scripts is not successful. I get the following errors:
Get-WMIObject : Provider load failure
At C:\Program Files\Application\KeyboardFilter.ps1:31 char:19
+ ... $predefined = Get-WMIObject -class WEKF_PredefinedKey #CommonParams |
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Write-Error : A positional parameter cannot be found that accepts argument 'is'.
At C:\Program Files\Application\KeyboardFilter.ps1:41 char:9
+ Write-Error $Id is not a valid predefined key
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-Error], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteErrorCommand
enable-windowsoptionalfeature : An attempt was made to load a program with an incorrect format.
At C:\Program Files\Application\ShellLauncher.ps1:4 char:1
+ enable-windowsoptionalfeature -online -featureName Client-EmbeddedShe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Enable-WindowsOptionalFeature], COMException
+ FullyQualifiedErrorId : Microsoft.Dism.Commands.EnableWindowsOptionalFeatureCommand
The installation process starts with administration permissions.
The first script adds key combinations to the Keyboard Filter (Windows 10 IoT feature).
The second scripts enable and configure the Shell Launcher (also Windows 10 IoT feature).
KeyboardFilter.ps1:
param (
[String] $ComputerName
)
$CommonParams = #{"namespace"="root\standardcimv2\embedded"}
$CommonParams += $PSBoundParameters
function Enable-Predefined-Key($Id) {
$predefined = Get-WMIObject -class WEKF_PredefinedKey #CommonParams |
where {
$_.Id -eq "$Id"
};
if ($predefined) {
$predefined.Enabled = 1;
$predefined.Put() | Out-Null;
Write-Host Enabled $Id
} else {
Write-Error $Id is not a valid predefined key
}
}
If I execute the Powershell scripts in a batchfile or on Powershell console, everything works fine. I also tried to execute the Powershell scripts during the installation process with Powershell x86 and x64, same errors in both cases.
Any hints, tips or solution for this problem?

Powershell runbook errors after update to OMS New Query Language

It turned out that after migration to New Query Language in OMS also WebhookData structure for alert has changed.
I was trying to change my powershell script (which is called at OMS alert via Automation Account runbook) and it works locally for the Input I've copied for some previous (updated) alerts but I cannot get it to work in Automation Account.
Can anyone tell why this don't work in Runbook but works locally?
Here is my runbook input: https://jsonblob.com/adf5e1c2-c948-11e7-af9e-2d30dd548850
I took it from here:
Script:
$WebhookData = '{"WebhookName":"OMS Alert Remediation b64051e5-b9c5-44db-b74f-51d7cf5a9df2","RequestBody":"{\"WorkspaceId\":\"8547d992-7979-46d0-912b-8fffeabe1c8b\",\"AlertRuleName\":\"SRVR slow response - TEST\",\"SearchQuery\":\"ApplicationInsights | where TelemetryType == \\\"Request\\\" and Computer startswith_cs \\\"SRVR\\\" and Computer != \\\"SRVR-DEVEL\\\" | summarize AggregatedValue = avg(RequestDuration) by bin_at(TimeGenerated, 4m, datetime(2017-11-12T10:32:00.0000000)), Computer | sort by TimeGenerated desc\",\"SearchResult\":{\"tables\":[{\"name\":\"PrimaryResult\",\"columns\":[{\"name\":\"TimeGenerated\",\"type\":\"datetime\"},{\"name\":\"Computer\",\"type\":\"string\"},{\"name\":\"AggregatedValue\",\"type\":\"real\"}],\"rows\":[[\"2017-11-12T10:28:00Z\",\"SRVR-06\",1535.2852333333333],[\"2017-11-12T10:24:00Z\",\"SRVR-06\",718.91287857142856]]}]},\"SearchIntervalStartTimeUtc\":\"2017-11-12T10:27:00Z\",\"SearchIntervalEndtimeUtc\":\"2017-11-12T10:32:00Z\",\"AlertThresholdOperator\":\"Greater Than\",\"AlertThresholdValue\":700,\"ResultCount\":2,\"SearchIntervalInSeconds\":300,\"LinkToSearchResults\":\"https://8547d992-7979-46d0-912b-8fffeabe1c8b.portal.mms.microsoft.com/#Workspace/search/index?_timeInterval.intervalEnd=2017-11-12T10%3a32%3a00.0000000Z&_timeInterval.intervalDuration=300&q=ApplicationInsights%20%20%7C%20where%20TelemetryType%20%3D%3D%20%5C%22Request%5C%22%20and%20Computer%20startswith_cs%20%5C%22SRVR%5C%22%20and%20Computer%20!%3D%20%5C%22SRVR-DEVEL%5C%22%20%20%7C%20summarize%20AggregatedValue%20%3D%20avg(RequestDuration)%20by%20bin_at(TimeGenerated%2C%204m%2C%20datetime(2017-11-12T10%3A32%3A00.0000000))%2C%20Computer%20%20%7C%20sort%20by%20TimeGenerated%20desc\",\"Description\":\"W runbook-u testujemy powershell workflow, zamiast powershel script \",\"Severity\":\"Critical\"}","RequestHeader":{"Connection":"Keep-Alive","Accept":"application/json","Host":"s2events.azure-automation.net","User-Agent":"OMS-Remediation","x-ms-request-id":"9be297e0-c196-45c0-ad23-3b513e165648"}}'
$Input = ConvertFrom-Json $WebhookData
$RequestBody = ConvertFrom-Json -InputObject $Input.RequestBody
$Computers = New-Object -TypeName System.Collections.ArrayList
foreach($row in $RequestBody.SearchResult.tables[0].rows)
{
$Computers.Add($row[1]) > $null
}
foreach ($Computer in $Computers | Get-Unique)
{
'Computer: ' + $Computer
Invoke-Command -Credential $c -ComputerName $Computer -ScriptBlock {
$date = Get-Date | Out-File -Append 'C:\tmp\test_log.txt'
}
}
And those are errors in Azure Portal:
1.
ConvertFrom-Json : Invalid JSON primitive: .
At line:9 char:10
+ $Input = ConvertFrom-Json $WebhookData
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
2.
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At line:10 char:46
+ $RequestBody = ConvertFrom-Json -InputObject $Input.RequestBody
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJs
onCommand
3.
Cannot index into a null array.
At line:14 char:17
+ foreach($row in $RequestBody.SearchResult.tables[0].rows)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
As you noticed the query language has changed. We have published a new sample here on how to parse results from the new language.
Look here:
https://learn.microsoft.com/en-us/azure/log-analytics/log-analytics-alerts-actions#webhook-actions
Have a look at the new sample and see if you can use that to parse the records.
Thanks,
Anirudh

Adding Shared Printer to Remote Computer via Powershell

I am unable to run an invoke-command script to install printers on a remote machine. My code works locally, but as soon as I pipe it into Invoke-command, i get errors.
Local:
$Printer = "\\server1\printer1"
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($Printer)
And this adds the printer just fine. I can do this same command on the remote computer with no issues. But when i tried to execute the command remotely I have the issues.
Remote:
$compname = "computer"
$Printer = "\\server1\printer1"
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer')}
Which returns the error "The printer name is invalid"
So I tried to see what the shell was sending to the remote computer with the following code, and everything in the write output looks good, but I still get errors:
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer'); write-host "(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('$Printer')"}
Output:
Exception calling "AddWindowsPrinterConnection" with "1" argument(s): "The printer name is invalid. (Exception from
HRESULT: 0x80070709)"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
+ PSComputerName : computer
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection('\\server1\printer1')
Edit 1/5/2015
So I've tried Paul's code with a number of different entries to the argumentlist. All have not worked so far. i think the first 3 are closer to an answer.
-ArgumentList ""\\server1\printer1""
-ArgumentList ""'\\server1\printer1'""
-ArgumentList "\"\\server1\printer1""
Results in:
Invoke-Command : A positional parameter cannot be found that accepts argument '\\server1\printer1'.
At line:1 char:1
+ Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Ne ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
-ArgumentList "'\\server1\printer1'"
-ArgumentList \'"\\server1\printer1"'
-ArgumentList \""\\server1\printer1""
-ArgumentList \"\\server1\printer1"
Result in:
Exception calling "AddWindowsPrinterConnection" with "1" argument(s): "The printer name is invalid. (Exception from
HRESULT: 0x80070709)"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
+ PSComputerName : sso-mxl327082y
Try this:
Invoke-Command -ComputerName $CompName -Scriptblock {(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($args[0]); write-host "(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($($args[0]))"} -ArgumentList "\\server1\printer1"
I think it´s because your $printer variable is placed between single quotes, variables between single quotes are not interpreted by powershell. So the printername your function probably gets is "$printer".
In case you wonder it is printed out correctly in your write-host statement because here the single quotes are inside a string.
you need to use $Using:yourvar to pass variables to the scriptblock
$compname = "computer"
$Printer = "\\server1\printer1"
Invoke-Command -ComputerName $CompName -Scriptblock
{
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($Using:$Printer)
}
I think it's because of the so called 'double hop problem', where your authentication isn't transfered to the next remote computer which is sharing the printer.
I tried to solve similar problem using add-printer and following this article double hop problem solution.
However, although it works with get-childitem etc. it doesn't work with add-printer cmdlet.