Select-Object throws an exception when used in a constrained session - powershell

When I configure a restricted PowerShell Session like so:
New-PSSessionConfigurationFile -Path c:\PSScripts\test.pssc `
-Description 'Delegation EndPoint Repro' `
-ExecutionPolicy Restricted `
-SessionType RestrictedRemoteServer `
-LanguageMode FullLanguage
Register-PSSessionConfiguration -Path 'c:\PSScripts\test.pssc' `
-Name TestSession `
-ShowSecurityDescriptorUI `
-AccessMode Remote `
-Force
Since the session is of type RestrictiedRemoteServer, I expect the Select-Object Cmdlet be available to end-users. Indeed, when users connect to this session and issue a Get-Command, Select-Object is returned as on of the available Cmdlets.
However when Select-Object is used (for example with -Last parameter), the following exception is thrown.
[localhost]: PS> Get-Command | Select-Object -Last 1
A parameter cannot be found that matches parameter name 'Last'.
+ CategoryInfo : InvalidArgument: (:) [Select-Object], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Select-Object
What am I missing?

Related

Update definition of SCEP on windows servers using powershell

i am trying to update the definition of SCEP on remote Windows Servers using MpCmdRun.exe which exists under "C:\ProgramData\Microsoft\Windows Defender\platform\*\MpCmdRun.exe. Unfortunately it is not accepting -filepath. says its null or empty. below is my code
$comp = "SRV1234"
$MpCmdRun = invoke-Command -ComputerName $comp -ScriptBlock {get-item -Path "C:\ProgramData\Microsoft\Windows Defender\platform\\*\MpCmdRun.exe" | Sort-Object -Property LastWriteTime -Descending |Select-Object -ExpandProperty fullname -First 1}
invoke-Command -ComputerName $comp -ScriptBlock {Start-Process -FilePath $MpCmdRun -ArgumentList "-signatureUpdate" -Wait}
Below is the error:
Cannot validate argument on parameter 'FilePath'. The argument is null
or empty. Provide an argument that is not null or empty, and then try
the command again.
+ CategoryInfo : InvalidData: (:) [Start-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.StartProcessCommand

PowerShell script to get logged in user

I am looking to run a script on a remote machine using an automation tool that runs the scripts in the system context.
What I have so far:
$userId = Get-Process -IncludeUserName explorer | % username | sort Username -Unique
Write-Host $userid.ToLower()
Results:
Get-Process : A parameter cannot be found that matches parameter name
'IncludeUserName'.
At line:1 char:39
+ $userId = Get-Process -IncludeUserName <<<< explorer | % username | sort Username -Unique
+ CategoryInfo : InvalidArgument: (:) [Get-Process], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetProcessCommand
ToLower : You cannot call a method on a null-valued expression.
At line:2 char:27
+ Write-Host $userid.ToLower <<<< ()
+ CategoryInfo : InvalidOperation: (ToLower:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Any ideas how to help this script? Or the cause of the errors?
The error says it all; the switch -IncludeUserName is not available on your computer. That's because it requires PowerShell 4.0 or above like Ansgar mentioned.
One solution is to install the latest Windows Mangement Framework (WMF) which includes the latest version of PowerShell.
You can also use the WMI-class Win32_Process to get the user and/or domain by calling the object's GetOwner()-method. Ex:
Get-WmiObject -Class Win32_Process -Filter "Name = 'explorer.exe'" |
ForEach-Object { $_.GetOwner() | % { "$($_.Domain)\$($_.User)" } } |
Sort-Object -Unique
the following script might help you. I'm not completely certain if the invoked command will get the remote logged in user, because I'm not on a work computer right now but it came from the internet so it must be true.
$Computers = (Get-Content "\\<sharedrive\<directory>\Computers.txt)
Foreach ($Computer in $Computers){ `
Invoke-Command -ComputerName $Computer -ScriptBlock `
{Get-WMIObject -Class Win32_ComputerSystem).Username} `
}

New-Object fails on PowerShell 2 with Constructor not found error

I have the below script running fine on PowerShell 5
$NetworkChange = New-Object System.Net.NetworkInformation.networkchange
Register-ObjectEvent -InputObject $NetworkChange -EventName NetworkAddressChanged -SourceIdentifier "NetworkChanged" -Action {
Write-Host "network switched"
$LanConnected=#(Get-WmiObject win32_networkadapter -filter "netconnectionstatus = 2" | Where-Object {$_.netconnectionid -like "*Local Area Connection*"})
If($LanConnected){
Get-WmiObject win32_networkadapter -filter "netconnectionstatus = 2" | Where-Object {$_.netconnectionid -like "*Wireless Network Connection*"} | ForEach-Object {$_.disable()}
}
Else {
Get-WmiObject win32_networkadapter | Where-Object {$_.netconnectionid -like "*Wireless Network Connection*"} | ForEach-Object {$_.enable()}
}
}
However it fails on PowerShell 2 with the below error related to the New-Object cmdlet
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Net.NetworkInformation.networkchange.
At line:1 char:11
+ New-Object <<<< System.Net.NetworkInformation.networkchange
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand
Any idea why it fails? Is there a different syntax for the New-Object cmdlet on PowerShell 2?
Note: Our estate is still on PowerShell 2 hence this struggle.
Thanks in advance
Steve
In PS5 works this code:
$NetworkChange = [System.Net.NetworkInformation.NetworkChange]::new()
PS2 says [System.Net.NetworkInformation.NetworkChange] doesn't contain a method named 'new'. So we can go around it by creating a variable 'classic' way:
New-Variable -Name NetworkChange -Value ([System.Net.NetworkInformation.NetworkChange])
$NetworkChange

Select-Object CmdLet fails when used inside a FunctionDefinition of New-PSSessionConfigurationFile

Consider this example below, where I am creating a constrained management end-point. My objective is to create a "proxy" function over the Get-EventLog CmdLet. This example, works as expected until I add | Select-Object -First 5. When I do this I get the following error message: "A parameter cannot be found that matches parameter name 'First'". Why?
$getAppEventLog = {
#this throws an error, see below
get-eventlog -log application | Select-Object -First 5
#this works
#get-eventlog -log application
}
New-PSSessionConfigurationFile -Path c:\PSScripts\panos.pssc `
-Description 'Delegation EndPoint Repro' `
-ExecutionPolicy Restricted `
-SessionType RestrictedRemoteServer `
-LanguageMode FullLanguage `
-FunctionDefinitions #{Name="Get-AppEventLog";ScriptBlock=$getAppEventLog; Options="AllScope"}
Unregister-pssessionconfiguration -name EventLogManagement -force
Test-PSSessionConfigurationFile -Path c:\PSScripts\panos.pssc
Register-PSSessionConfiguration -Path 'c:\PSScripts\panos.pssc' `
-Name EventLogManagement `
-ShowSecurityDescriptorUI `
-AccessMode Remote `
-Force
Enter-PSSession -ComputerName localhost -ConfigurationName EventLogManagement
Get-AppEventLog
Select-Object : A parameter cannot be found that matches parameter name 'First'.
At line:2 char:51
+ get-eventlog -log application | Select-Object -First 5
+ ~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Select-Object], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Select-Object
PowerShell Info
PS C:\Windows\system32> $PSVersionTable
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.34209
BuildVersion 6.3.9600.17400
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion 2.2
After thinking about this, I realized the issue could be reproduced in a simpler way - without the function definition.
When SessionType is equal to RestrictedServer, the following two Cmdlets are available: Get-Command and Select-Object. Therefore, I could reproduce my issue by simply executing something like this:
[localhost]: PS> Get-Command | Select-Object -first 1
A parameter cannot be found that matches parameter name 'first'.
+ CategoryInfo : InvalidArgument: (:) [Select-Object], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Select-Object
Given that, I can create a session that reproduces the issue, like so:
New-PSSessionConfigurationFile -Path c:\PSScripts\panos.pssc `
-Description 'Delegation EndPoint Repro' `
-ExecutionPolicy Restricted `
-SessionType RestrictedRemoteServer `
-LanguageMode FullLanguage
Unregister-pssessionconfiguration -name EventLogManagement -force
Test-PSSessionConfigurationFile -Path c:\PSScripts\panos.pssc
Register-PSSessionConfiguration -Path 'c:\PSScripts\panos.pssc' `
-Name EventLogManagement `
-ShowSecurityDescriptorUI `
-AccessMode Remote `
-Force
Hence, I can rephrase my original question as: Why does Select-Object Cmdlet does not work in a restricted session, given the above registration parameters.
I've had the same issue, creating a PS endpoint as a wrapper around the PSPKI module. The PSPKI module uses the Select-Object as well, giving the same error.
The solution for me was to update my endpoint .psrc file to include an AliasDefinition for Select-Object to point to the FQDN Select-Object.
AliasDefinitions = #{ Name = 'Select-Object' ; Value = 'Microsoft.PowerShell.Utility\Select-Object' }
See also: https://jamesone111.wordpress.com/2016/07/01/just-enough-admin-and-constrained-endpoints-part-2-startup-scripts/
Grtx,
BvZanten
Instead can you please try to use:
Get-EventLog -log application -newest 5
With a SessionType RestrictedRemoteServer the function Select-Object is not the same as in a Default-SessionType:
RestrictedRemoteServer. Includes only the following proxy functions: Exit-PSSession, Get-Command, Get-FormatData, Get-Help, Measure-Object, Out-Default, and Select-Object. Use the parameters of this cmdlet to add modules, functions, scripts, and other features to the session.
That issue is described here with some workarounds: Constrained PowerShell endpoints – Visible cmdlets, session types, and language modes:
A proxy function is a wrapper function around the original cmdlet that modifies the capabilities of the cmdlet, for example, by adding or removing parameters.

PowerShell Path Parameter Invoke-Command (UnauthorizedAccessException)

When running this simple script I am receiving the error message:
+ CategoryInfo : OpenError: (:) [Import-Csv], UnauthorizedAccessException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand
Param(
[string]$Path,
[string]$Credential
)
Invoke-Command –cn DC –Credential $Credential -ArgumentList $Path –ScriptBlock `
{import-csv -Path $args[0] | select-object –property `
#{name='Identity';expression={$_.username}},#{name='Fax';expression={$_.'fax number'}} `
| foreach{Set-ADUser -Identity $_.identity -Fax $_.fax -Confirm:$false}}
Any idea why this may be happening? I have correct permissions the the path that I am using.
I found the issue and it was because I was not including the CSV file in my path. I was pointing to C:\Files\CSV instead of C:\Files\CSV\fax-users.csv.