PowerShell and the Windows Event Log

What was once easy, is now exceptionally convoluted and difficult. There is some chance that your automated script is already logging to the event log (PowerShell Core/Operational) but there’s every chance that log is full of Warnings too. Good luck. LOL

New-WinEvent

The New-WinEvent cmdlet creates an Event Tracing for Windows (ETW) event for an event provider. You can use this cmdlet to add events to ETW channels from PowerShell.

New-WinEvent [-ProviderName] <String> [-Id] <Int32> [-Version <Byte>] [[-Payload] <Object[]>] [<CommonParameters>]

Examples:

New-WinEvent -ProviderName Microsoft-Windows-PowerShell -Id 45090 -Payload @("Workflow", "Running")

More on New-WinEvent here.

Get-WinEvent

The Get-WinEvent cmdlet gets events from event logs, including classic logs, such as the System and Application logs. The cmdlet gets data from event logs that are generated by the Windows Event Log technology introduced in Windows Vista and events in log files generated by Event Tracing for Windows (ETW). By default, Get-WinEvent returns event information in the order of newest to oldest.

Get-WinEvent [[-LogName] <String[]>] [-MaxEvents <Int64>] [-ComputerName <String>] [-Credential <PSCredential>] [-FilterXPath <String>] [-Force] [-Oldest] [<CommonParameters>]

More on Get-WinEvent here.

The post below is the deprecated way of interacting with the Event Log from PowerShell. In Powershell 7 onwards, use New-WinEvent and Get-WinEvent cmdlets.

The command Get-Command -Name *Event will still list the deprecated commands shown below but they will not work and will error with “The term ‘New-EventLog’ is not recognised as a name of a cmdlet…”

The command Get-Command -Name *WinEvent will list the supported cmdlets, namely New-WinEvent and Get-WinEvent

PowerShell Commands to interact with Windows Event Log

New-EventLog
Get-EventLog
Show-EventLog
Clear-EventLog
Write-EventLog
Limit-EventLog
Remove-EventLog

New-EventLog

Creates a new event log and a new event source on a local or remote computer.
This cmdlet creates a new classic event log on a local or remote computer. It can also register an event source that writes to the new log or to an existing log.


New-EventLog
[-LogName]
[-Source]
[[-ComputerName] ]
[-CategoryResourceFile ]
[-MessageResourceFile ]
[-ParameterResourceFile ]
[]

Get-EventLog

Gets the events in an event log, or a list of the event logs, on the local computer or remote computers.


Get-EventLog
[-LogName]
[-ComputerName ]
[-Newest ]
[-After ]
[-Before ]
[-UserName ]
[[-InstanceId] ]
[-Index ]
[-EntryType ]
[-Source ]
[-Message ]
[-AsBaseObject]
[]

Show-EventLog

Displays the event logs of the local or a remote computer in Event Viewer.
The Show-EventLog cmdlet opens Event Viewer on the local computer and displays in it all of the classic event logs on the local computer or a remote computer.


Show-EventLog
[[-ComputerName] ]
[]

Clear-EventLog

Clears all entries from specified event logs on the local or remote computers.
The Clear-EventLog cmdlet deletes all of the entries from the specified event logs on the local computer or on remote computers. To use Clear-EventLog, you must be a member of the Administrators group on the affected computer.


Clear-EventLog
[-LogName]
[[-ComputerName] ]
[-WhatIf]
[-Confirm]
[]

Write-EventLog

Writes an event to an event log.
To write an event to an event log, the event log must exist on the computer and the source must be registered for the event log.


Write-EventLog
[-LogName]
[-Source]
[[-EntryType] ]
[-Category ]
[-EventId]
[-Message]
[-RawData ]
[-ComputerName ]
[]

Limit-EventLog

Sets the event log properties that limit the size of the event log and the age of its entries.
The Limit-EventLog cmdlet sets the maximum size of a classic event log, how long each event must be retained, and what happens when the log reaches its maximum size. You can use it to limit the event logs on local or remote computers.


Limit-EventLog
[-LogName]
[-ComputerName ]
[-RetentionDays ]
[-OverflowAction ]
[-MaximumSize ]
[-WhatIf]
[-Confirm]
[]

Remove-EventLog

Deletes an event log or unregisters an event source.
The Remove-EventLogcmdlet deletes an event log file from a local or remote computer and unregisters all its event sources for the log. You can also use this cmdlet to unregister event sources without deleting any event logs.


Remove-EventLog
[[-ComputerName] ]
[-LogName]
[-WhatIf]
[-Confirm]
[]

Example: Write events from a powershell script to the Windows Event Viewer Application Log.

First register a new Application EventLog source.

New-EventLog -LogName Application -Source 'MyScript.ps1'

The Event Log itself requires five pieces of information before an event can be written to it.

  • LogName (Application)
  • Source (Script Name)
  • EventID
  • EntryType (Information, Error or Warning)
  • Message

The following code demonstrates how you might gather these pieces of information inside a statement and how you’d then write the event itself.

$filePath = 'C:\MyFile.txt'

$parameters = @
{

  'LogName'  = 'Application'

  'Source'  = 'MyScript.ps1'

}

if (Test-Path –Path $filePath) 
{

  $parameters  += @{

  'EventId'  = 1111 

  'EntryType'  = 'Information'

  'Message'  = 'The file already exists'

  }

  Write-EventLog  @parameters

} 
else 
{

  $parameters  += @{

  'EventId'  = 1112

  'EntryType'  = 'Error'

  'Message'  = 'The file does not exist'

  }

  Write-EventLog @parameters

  }

Top Tip: You may already have a Function in your script to perform Logging to a file. You could augment it to include some code to add an event to the Windows event log depending on the outcome of the script or code loop.

Did you like this?
Tip cyberfella with Cryptocurrency

Donate Bitcoin to cyberfella

Scan to Donate Bitcoin to cyberfella
Scan the QR code or copy the address below into your wallet to send some bitcoin:

Donate Bitcoin Cash to cyberfella

Scan to Donate Bitcoin Cash to cyberfella
Scan the QR code or copy the address below into your wallet to send bitcoin:

Donate Ethereum to cyberfella

Scan to Donate Ethereum to cyberfella
Scan the QR code or copy the address below into your wallet to send some Ether:

Donate Litecoin to cyberfella

Scan to Donate Litecoin to cyberfella
Scan the QR code or copy the address below into your wallet to send some Litecoin:

Donate Monero to cyberfella

Scan to Donate Monero to cyberfella
Scan the QR code or copy the address below into your wallet to send some Monero:

Donate ZCash to cyberfella

Scan to Donate ZCash to cyberfella
Scan the QR code or copy the address below into your wallet to send some ZCash:

Automated FTP Operations from PowerShell 7 using WinSCP .NET Assembly and WinSCP PowerShell Module.

This is the simplest method of automating ftp operations from PowerShell that I can come up with, having explored MANY incredibly convoluted alternatives.

It is an absolute minimum viable product that can be built upon, consisting of two downloadables that compliment one another and eight commands that probably do everything you need, and do it in a single command.

A link to the wiki for all the cmdlets is given in step 10 below.

Once the WinSCP module is installed, interfacing with an FTP server is as easy as this…
CerberusFTP Server displaying the inbound session from PowerShell using WinSCP cmdlets that call WinSCP .NET Assembly winSCPnet.dll
Don’t forget to close the ftp session when you’re done….
….and the session disappears from Cerberus FTP Server.

0. Download Software

Download matching versions of the Assembly and Cmdlets (5.17.10.0). The most recent version of the Automation .NET Assembly is 5.19.6.0 but you may have issues talking to WinSCP 5.19.6.0 using version 5.17.10.0 Cmdlets such as New-WinSCPSession where it complains about the winscp.exe version not matching the winscpnet.dll version.

WinSCP Automation .NET Assembly

https://sourceforge.net/projects/winscp/files/WinSCP/5.17.10/

WinSCP PowerShell Cmdlets (PowerShell Module)

https://github.com/dotps1/WinSCP/releases/download/WinSCP-PowerShell-v5.17.10.0/WinSCP.zip

1. Install WinSCP FTP Module in PowerShell 7

Install-Module -Name WinSCP
Import-Module -Name WinSCP
Add-Type -Path "WinSCPnet.dll"

2. Create encrypted credentials .xml file for use when connecting to ftp server automatically

$credential = Get-Credential
$credential | Export-Clixml ftpcredentials.xml
$ftpcredentials = Import-Clixml ftpcredentials.xml

3. Establish a session with an FTP Server

$ftpsessionoptions = New-WinSCPSessionOption -Credential $ftpcredentials -HostName "ftp.cyberfella.co.uk" -Protocol ftp

New-WinSCPSession -SessionOption $ftpsessionoptions

4. See if a file exists on the ftp server

Test-WinSCPPath -Path "/*.done"         


                False

5. Receive a file

Receive-WinSCPItem -RemotePath /ftptest.txt


                   Destination: C:\Users\matt\Documents\WindowsPowerShell\My Code

                IsSuccess FileName
                --------- --------
                True      ftptest.txt

6. Send a file

 Send-WinSCPItem -LocalPath "ftptest.txt"


                   Destination: \

                IsSuccess FileName
                --------- --------
                True      ftptest.txt

7. Send a folder and its entire contents (recursive by default)

Send-WinSCPItem -LocalPath "FTPTest"


                   Destination: \FTPTest

                IsSuccess FileName
                --------- --------
                True      {FTP-Functions-MB.ps1, ftptest.txt, ListFTP-MB.ps1}

8. Receive a folder and its entire contents (recursive by default)

Receive-WinSCPItem -RemotePath /FTPTest


                   Destination: C:\Users\matt\Documents\WindowsPowerShell\My Code\FTPTest

                IsSuccess FileName
                --------- --------
                True      {FTP-Functions-MB.ps1, ListFTP-MB.ps1, ftptest.txt}

9. Close Session to FTP Server

Remove-WinSCPSession

10. Wiki doc for all cmdlets here

https://github.com/dotps1/WinSCP/wiki

Additional commands required for Secure FTP (SSH Hostkey Fingerprint)

The example above was kept as simple as possible to demonstrate the minimum number of steps in order to “get things working”. Now we can build upon those steps and establish an sftp connection to the FTP Server.

Additional commands to set up an sftp session

Import-Module -Name WinSCP
Add-Type -Path "WinSCPnet.dll"

$ftpcredentials = Import-Clixml ftpcredentials.xml

$ftpsessionoptions = New-WinSCPSessionOption -Credential $ftpcredentials -HostName "10.0.2.15" -Protocol sftp

$sshHostKeyFingerprint = Get-WinSCPHostKeyFingerprint -SessionOption $ftpsessionoptions -Algorithm SHA-256

$ftpsessionoptions.SshHostKeyFingerprint = $sshHostKeyFingerprint

New-WinSCPSession -SessionOption $ftpsessionoptions

Cerberus FTP Server showing the sftp connection

Send-WinSCPItem -LocalPath "FTPTest"

Cerberus FTP Server Log entries showing the connection and the recursive transfer of a folder containing multiple files.

Receive-WinSCPItem -RemotePath /FTPTest

Recursively downloading a folder containing multiple files over sftp

Remove-WinSCPSession

The session disappears from Cerberus

My Powershell Code

# Pre-requisites
# EXECUTION POLICY SET TO BYPASS (TEST ENV)
# https://docs.microsoft.com/en-gb/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.2
# Set-ExecutionPolicy -ExecutionPolicy ByPass

# WinSCP Automation .NET Assembly
# https://winscp.net/download/WinSCP-5.19.6-Automation.zip    #WINSCP AUTOMATION .NET LIBRARY DLL
# https://winscp.net/eng/docs/library_powershell#example      #NOTES ON INSTALLATION OF DLL
# https://dotps1.github.io/WinSCP/                            #WINSCP CMDLETS MODULE

# Install (Run PowerShell as Administrator)
# Install-Module -Name WinSCP

# Import Module
Import-Module -Name WinSCP

# Cmdlets
# Get-Command -Module WinSCP

# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"

#Create Credential
#Set credentials to a PSCredential Object.
#$credential = Get-Credential
#Export credential to xml file
#$credential | Export-Clixml ftpcredentials.xml
#Import credential from xml file
$ftpcredentials = Import-Clixml ftpcredentials.xml

#VARIABLES SECTION
$ftphost="10.0.2.15"
$ftproot="/"
$ftpdirectory="FTPTest/"
$SendItem = $ftpdirectory + ""
$ReceiveItem = $ftpdirectory + ""
$FileFilter = "*"
#END OF VARIABLES SECTION

#FUNCTIONS SECTION
function Connect-FTP {
    #Connects using sftp to ftp server
    Write-Host "Connecting to FTP Server $ftphost..."
    $ftpsessionoptions = New-WinSCPSessionOption -Credential $ftpcredentials -HostName $ftphost -Protocol sftp
    $sshHostKeyFingerprint = Get-WinSCPHostKeyFingerprint -SessionOption $ftpsessionoptions -Algorithm SHA-256
    $ftpsessionoptions.SshHostKeyFingerprint = $sshHostKeyFingerprint
    New-WinSCPSession -SessionOption $ftpsessionoptions
    Write-Host "Connected Successfully to FTP Server $ftphost."
}
function Disconnect-FTP {
    #Disconnects session to ftp server
    Write-Host "Disconnecting from FTP Server $ftphost..."
    Remove-WinSCPSession
    Write-Host "Disconnected."
}
function List-FTP {
    #Gets a list of the files matching the filter in the specified ftp directory only (1 level)
    Connect-FTP
    Write-Host "Listing files in $ftpdirectory..."
    $fileitems = Get-WinSCPChildItem -Path $ftproot$ftpdirectory -Depth 1 -File -Filter $FileFilter
    Disconnect-FTP
}   
function Send-FTP {
    #Sends a specified local file or recursive directory's contents to ftp server
    Connect-FTP
    Write-Host "Sending everything in $SendItem to $ftphost..."
    Send-WinSCPItem -LocalPath $SendItem
    Write-Host "Finished sending."
    Disconnect-FTP
}
function Receive-FTP {
    #Receives a specified remote file or directory on the ftp server recursively by default
    Connect-FTP
    Write-Host "Receiving file(s) in $ReceiveItem from $ftphost..."
    $fileitems = Receive-WinSCPItem -RemotePath $ReceiveItem
    Write-Host "Finished receiving."
    Disconnect-FTP
}
#END OF FUNCTIONS SECTION

#MAIN CODE
List-FTP
Receive-FTP
Send-FTP
#END OF MAIN CODE
Executing the script above to list files on an ftp server over sftp, download a folder and upload a folder
Did you like this?
Tip cyberfella with Cryptocurrency

Donate Bitcoin to cyberfella

Scan to Donate Bitcoin to cyberfella
Scan the QR code or copy the address below into your wallet to send some bitcoin:

Donate Bitcoin Cash to cyberfella

Scan to Donate Bitcoin Cash to cyberfella
Scan the QR code or copy the address below into your wallet to send bitcoin:

Donate Ethereum to cyberfella

Scan to Donate Ethereum to cyberfella
Scan the QR code or copy the address below into your wallet to send some Ether:

Donate Litecoin to cyberfella

Scan to Donate Litecoin to cyberfella
Scan the QR code or copy the address below into your wallet to send some Litecoin:

Donate Monero to cyberfella

Scan to Donate Monero to cyberfella
Scan the QR code or copy the address below into your wallet to send some Monero:

Donate ZCash to cyberfella

Scan to Donate ZCash to cyberfella
Scan the QR code or copy the address below into your wallet to send some ZCash: