Информация по sec

A listing of the more widely-used PowerShell commands and a brief explanation about each command is provided below. Some commands can be referenced by an alias or cmdlet name, while other commands can only be referenced by a cmdlet name.

CSV

REST

HTTP

Do you want to run a PowerShell command on a remote computer or server? Then you don’t need to open a remote desktop connection, because you can just use the PowerShell Invoke-Command for that.

Invoke-Command allows you to run PowerShell commands and scripts on one or more remote computers. while redirecting the results to your own console. This makes it a great cmdlet to manage remote devices quickly.

In this article

In this article, we are going to take a look at what is required to use Invoke-Command and how to use the cmdlet.

Adversaries may abuse PowerShell commands and scripts for execution.
PowerShell is a powerful interactive command-line interface and scripting environment included in the Windows operating system. (Citation: TechNet PowerShell)
Adversaries can use PowerShell to perform a number of actions, including discovery of information and execution of code

Sigma rule (View on GitHub)

Powershell XML Execute Command Adversaries may abuse PowerShell commands and scripts for execution. PowerShell is a powerful interactive command-line interface and scripting environment included in the Windows operating system. (Citation: TechNet PowerShell) Adversaries can use PowerShell to perform a number of actions, including discovery of information and execution of code- - - - all of selection_*
 #Fucntion to manipulate the data
Function writeToServer
{ param($server,$Time) # Data preparation for loading data into SQL table $InsertResults = @" INSERT INTO [ServerTimeSync].[dbo].[ServerTimes](SystemName,ShownTimeOnServer) VALUES ('$SERVER','$Time') "@ #call the invoke-sqlcmdlet to execute the query Invoke-sqlcmd @params -Query $InsertResults } foreach ($COMPUTER in $COMPUTERS){ icm $COMPUTER -ScriptBlock {$ENV:COMPUTERNAME $computer get-date -Format "MM-dd-yyyy hh:mm:ss tt" $script:sdate = get-date -Format "MM-dd-yyyy hh:mm:ss tt" } writeToServer $computer $script:sdate
}

asked Aug 22, 2023 at 11:31

Edgar's user avatar

  • You can only pass (the values of) local variables TO a remote command, via the $using: scope.

    • $using: references are embedded directly in the remote script block and are an alternative to passing values via arguments (parameters), using -ArgumentList – see this answer for examples. In both cases only the value of a local variable is getting passed, not the variable object itself.
    • That is, you fundamentally cannot set variables for the caller from a remote script block.

Note that the above applies to all out-of-runspace / cross-process calls, e.g. also to Start-Job – see this answer for details.

You can also streamline your command by using parallel processing:

Invoke-Command -ComputerName $COMPUTERS -ScriptBlock { Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
} | ForEach-Object { writeToServer $_.PSComputerName $_ }
  • If you pass multiple computer names to Invoke-Command‘s -ComputerName parameter, processing occurs in parallel, but the ordering of the outputs isn’t guaranteed to match the order in which the names were passed.

answered Aug 22, 2023 at 12:02

mklement0's user avatar

67 gold badges673 silver badges862 bronze badges

This is how you utilize $using: correctly

$MyString = 'Test 123'
Invoke-Command . -ScriptBlock {Write-Output $MyString} # produces no output because $MyString is empty
Invoke-Command . -ScriptBlock {Write-Output $using:MyString} # produces correct output because $MyString contains the string
$MyString = 'Test 123'
$Capture = Invoke-Command . -ScriptBlock {Write-Output $using:MyString}
Write-Host $Capture

answered Aug 22, 2023 at 12:11

:/>  Ключи Windows 10 Enterprise ltsc x64 2020-2021 - Скачать бесплатно программы 2021-2022 для Windows и Android

David Trevor's user avatar

David Trevor

1 gold badge9 silver badges31 bronze badges

Windows DFIR notes are no longer maintained on InfoSec-Notes. Updated versions can be found on: artefacts.help.

Windows PowerShell version 2.0, and prior versions, provide few useful audit settings, thereby limiting the availability of evidence (such as a command history).

  • Microsoft-Windows-PowerShell\Analytic.etl (non default)

  • Microsoft-Windows-WinRM\Analytic.etl (non default)

The events linked to remote PowerShell activity, conducted through the WinRM service, are detailed in the Lateral movements section.

Additionally, if enabled, AppLocker will record PowerShell activity in the Microsoft-Windows-AppLocker\MSI and Script hive.

Note that PowerShell 2.0, and prior versions, provide limited logging capacities and thereby limit the availability of evidence, such as the interactive command history executed through PowerShell console.

  • -Enc / -e

  • -nop / bypass

  • IEX / Invoke-Expression

  • ICM / Invoke-command

  • Net.WebClient / io.

  • DownloadString / DownloadFile

  • // / http / ftp / cifs / smb / etc.

While the occurrence of these keywords may entail malicious activities, their absence is not a formal proof of lack of malicious PowerShell activity as PowerShell code can be deeply obfuscated.

The PSDecode PowerShell script can be used to deobfuscate malicious PowerShell scripts that have several layers of encodings.

PowerShell Windows events

HiveEvent IDConditionsDescription

Engine state is changed from None to Available.
Logged on the start of any local or remote PowerShell activity (execution of powershell.exe).
The HostApplication field record the binary path at the origin of the powershell activity and contain the commandline arguments provided to powershell.exe.
If the Hostname field is equal to :
ConsoleHost, the event concern a local activity
ServerRemoteHost, the event occured du to PowerShell remoting activity.
The RunaspaceId identify the PowerShell activity and can be linked to the session termination (EID 403). Note that however this event cannot be strictly correlated to a logon session.

Engine state is changed from Available to Stopped.
Logged at the end of any local or remote PowerShell activity (execution of powershell.exe) and contains the same level of information as the EID 400 events.
The RunaspaceId identify the PowerShell activity and can be linked to the session start (EID 400). Note that however this event cannot be strictly correlated to a logon session.

PowerShell 2.0
Requires $LogCommandLifeCycleEvent to be set to true (non default)

Command "<COMMAND>" is Started.
Logged whenever a PowerShell command is executed, but can be bypassed by starting PowerShell using the -NoProfile / -nop flag.

PowerShell 2.0
Requires $LogCommandLifeCycleEvent to be set to true (non default)

Command "<COMMAND>" is Stopped.
Logged whenever a PowerShell command finish its execution, but can be bypassed by starting PowerShell using the -NoProfile / -nop flag.

Provider "<PROVIDER_NAME>" is Started.
Logs the start and stop of PowerShell providers.
Similarly to the events EID 400 and EID 403, this event include the HostApplication field.
If the provider is WSMan (“Provider WSMan Is Started”), the event, logged on both the client and remote systems, indicate the use of PS remoting.
If the PowerShell activity relies on built-in alias, such as IEX, an event will be generated for the Alias provider.

PowerShell 3.0
Requires PowerShell Module Logging to be enabled (EnableModuleLogging registry key set to 1)

Windows PowerShell has started an IPC listening thread on process: <PID> in AppDomain: <DOMAIN>.
Indicates that a PowerShell AppDomain was started.
Usually logged upon the start of the PowerShell console, in between events EID: 40961 and EID: 40962.

Microsoft-Windows-WinRM\Operational

WinRM events on destination host.

Microsoft-Windows-WinRM\Operational

WinRM events on source host.

Microsoft-Windows-AppLocker\MSI and Script

Require AppLocker to be enabled and running in Audit only mode

<SCRIPT_PATH> was allowed to run.
Logged upon the execution of a local PowerShell script.

Microsoft-Windows-AppLocker\MSI and Script

Require AppLocker to be enabled and running in Audit only mode

<SCRIPT_PATH> was allowed to run but would have been prevented from running if the AppLocker policy were enforced.
Logged upon the execution of a local PowerShell script.

Requires Audit Process Creation to be enabled


Wrapping Up

The PowerShell Invoke-Command is a great tool to manage remote computers. It allows you to quickly execute a command without the need to open a remote desktop. Especially when you need to run the command on multiple computers at once.

Make sure that you also look at the New-PSSession cmdlet, this is really a better option when you need to execute multiple commands on a remote computer.

I hope you found this article helpful, if you have any questions, just drop a comment below.

Using the Invoke-Command

The Invoke-Command in PowerShell allows you to run a command or script on a remote computer. When you need to run multiple commands on a remote computer, then it’s better to use the New-PSSession cmdlet.

The structure of the Invoke-Command is pretty straightforward, but nevertheless, there are still quite a few options (parameters) that we can use:

ParameterDescription
ComputerNameComputername or IP Address to run the command on. For multiple computer, separate the names with a comma ,
CredentialCredentials to connect to remote computer
FilePathSpecifies the path to a local script to run on the remote computer(s)
AsJobRun the remote command as background job on the local computer
InDisconnectedSessionUsed to run the command in a disconnected session on the remote computer
ScriptBlockScript or command to run
ArgumentListUsed to pass arguments to the cmdlet in the scriptblock
Invoke-Command Parameters
Invoke-Command -ComputerName la-srv-dc01 {Get-ComputerInfo}
PowerShell invoke-command

This will run the command Get-ComputerInfo on the domain controller (la-srv-dc01) and return the results to the console.

Running a Script

The example below works fine, but it’s a bit harder to read this way:

Invoke-Command -ComputerName la-srv-dc01 -ScriptBlock {Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, MediaType, @{Name="FreeSpace (GB)"; Expression={"{0:N2}" -f ($_.FreeSpace / 1GB)}}}
$script = { Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, MediaType, @{Name="FreeSpace (GB)"; Expression={"{0:N2}" -f ($_.FreeSpace / 1GB)}}
}
Invoke-Command -ComputerName la-srv-dc01 -ScriptBlock $script

The third option is to store the script on your local computer and refer to the script using the -FilePath parameter:

Invoke-Command -ComputerName la-srv-dc01 -FilePath c:\test\diskInfo.ps1

Run on Multiple Computers

One of the big advantages of the Invoke-Command cmdlet in PowerShell is that you can also run it on multiple computers simultaneously. There are a couple of options to do this, we can simply specify the computer names separated by a comma:

Invoke-Command -ComputerName la-srv-dc01, la-srv-app01, la-srv-file01 -FilePath c:\test\diskInfo.ps1

Another option to write this is to use a hashtable and splatting. Splatting the parameters will make your script easier to read when you need to add a lot of properties.

$parameters = @{ ComputerName = 'la-srv-dc01', 'la-srv-app01', 'la-srv-file01', 'la-win11-lab03' ScriptBlock = { Get-ComputerInfo } }
Invoke-Command @parameters

When you need to run a command on many computers, let’s say a hundred or more, then you want to minimize the load on your local computer. For this, we can use the InDisconnectedSession parameter.

If you run the Invoke-Command cmdlet normally, then your local computer will connect to the remote computer, start the script, wait for the results, and disconnect. The waiting parts consume the most time and resources from your local computer, especially when connecting to 100 or more computers.

With the InDisconnectedSession parameter, the cmdlet will only connect to the remote computer, start the script, and then disconnect. This reduces the whole process time significantly.

$parameters = @{ ComputerName = (Get-Content -Path C:\Test\Servers.txt) InDisconnectedSession = $true FilePath = '\\lazyadmin\scripts\InstallWinUpdates.ps1'
}
Invoke-Command @parameters

Using Credentials

You will need to have permission on the remote computer to run the PowerShell commands. When running the command on a server you probably won’t have the correct permission from your local workstation.

Invoke-Command -ComputerName la-srv-dc01 -Credential lazyadmin\administrator -Scriptblock {Get-ComputerInfo}

Just like with most PowerShell cmdlets, you can also pass a credential object to the -Credential cmdlet. This method is especially handy when you want to run multiple commands or need to run different commands on different remote computers:

$cred = Get-Credential
Invoke-Command -ComputerName la-srv-dc01 -Credential $cred -Scriptblock {Get-ComputerInfo}

Include Local Variables

$path = "c:\test"
Invoke-Command -ComputerName la-srv-dc01 -Scriptblock {Get-Childitem -Path $path}

The example above isn’t going to work. The remote computer, in this case la-srv-dc01, doesn’t know what the variable $path is, so it won’t return any results.

$path = "c:\test"
Invoke-Command -ComputerName la-srv-dc01 -Scriptblock {Get-Chiditem -Path $Using:path}

Prerequisites Invoke-Command

To check if a remote computer accepts Remote Management, we can use a simple PowerShell command, Test-WSMan

Test-WSMan -Computername la-srv-dc01
remote powershell

If you get an error that you cannot connect to the destination, then the service Windows Remote Management is not running. To enable it we can use the PowerShell cmdlet Enable-PSRemoting on the remote computer:

Enable-PSRemoting

The advantage of this command is that it not only starts the Remote Management services but also sets it to start automatically and creates the required exception rule in the firewall.

But even a better option is to create a new Group Policy Object (GPO). This way you can easily enable the Remote Management service on multiple computers or servers.

You can find the policy setting in Computer Configuration > Windows Settings > Security Settings > System Services.

Firewall rule

We can use the same GPO to create the inbound rule as well.

  1. Navigate to Computer Configuration > Windows Settings > Security Settings > Windows Defender Firewall with Advanced Security
  2. Right-click on Inbound Rules and select New Rule
  3. Select Predefined and choose Windows Remote Management
  4. Select the rule with profile Domain, Private
  5. Choose Allow the connection and click finish
Windows Remote Management

Make sure that the new policies are updated on the server/client, by using the GPUpdate command.