PowerShell Functions to Get Logged On User and Logoff Logged On User

Two helpful PowerShell functions to help you check who is logged on remotely and to remotely log them off.

Remotely Get a Logged On User

This Get-LoggedOnUser will use Get-WmiObject to tell you who is logged on to a remote computer. You may use a comma-delimited list of computer names.

Function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Get-LoggedOnUser
	{
		[CmdletBinding()]
		param
		(
			[Parameter()]
			[ValidateScript({ Test-Connection -ComputerName $_ -Quiet -Count 1 })]
			[ValidateNotNullOrEmpty()]
			[string[]]$ComputerName = $env:COMPUTERNAME
		)
	foreach ($comp in $ComputerName)
		{
			$output = @{ 'ComputerName' = $comp }
			$output.UserName = (Get-WmiObject -Class win32_computersystem -ComputerName $comp).UserName
			[PSCustomObject]$output
		}
	}

Example:

1
Get-LoggedOnUser -ComputerName "SERVER01", "SERVER02", "SERVER03"

Remotely Logoff a Logged On User

This LogOff-LoggedOnUser function will use Get-WmiObject to log off a user. You may use a comma-delimited list of computer names.

Function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function LogOff-LoggedOnUser
	{
		[CmdletBinding()]
		param
		(
			[Parameter()]
			[ValidateScript({ Test-Connection -ComputerName $_ -Quiet -Count 1 })]
			[ValidateNotNullOrEmpty()]
			[string[]]$ComputerName = $env:COMPUTERNAME
		)
		foreach ($comp in $ComputerName)
		{
			$output = @{ 'ComputerName' = $comp }
			$output.UserName = (Get-WmiObject -Class win32_operatingsystem -ComputerName $comp).Win32Shutdown(4)
			[PSCustomObject]$output
		}
	}

Example:

1
LogOff-LoggedOnUser -ComputerName "SERVER01", "SERVER02", "SERVER03"

Ticketmaster requires users to agree to their Terms of Use before reading them

When you visit www.ticketmaster.com you might notice in the footer a statement that says “By continuing past this page, you agree to our Terms of Use.”

In order for a Ticketmaster customer to read either their Terms of Use or their Privacy Policy, they would have to blindly agree to both before reading them.

I would like to know what both the Terms of Use and Privacy Policy say before agreeing to them. Neither Ticketmaster Support at 1 (800) 653-8000 nor Twitter accounts @ticketmaster.com and @TMfanSupport offered a way.

It appears that if you want to use Ticketmaster.com and first visited any page other than the Terms of Use page, you’ll have to agree to their terms before reading them.

Use IPdeny to create Mail flow rules (transport rules) in Exchange Online

This PowerShell script will help an Office 365 administrator or Exchange Online administrator block incoming email messages originating from specific countries using data from IPdeny.

About IPdeny country block downloads

IPdeny compiles raw data from regional internet registries and offers free of charge country IP address block downloads. Their country IP zone files can be used to minimize on-line fraud, SPAM, floods, or brute force attacks. This is the source of information my script will use.

About Mail flow rules (transport rules) in Exchange Online

Mail flow rules (also known as transport rules) identify and take action on messages that flow through your Office 365 organization. Mail flow rules take action on messages while they’re in transit before the message is delivered to a mailbox. This is the target that my script will use to create rules using IPdeny data.

About my PowerShell script

This PowerShell script will do the following: * Log you into your Office 365 Exchange environment * Download two .tar.gz files from IPdeny.com (IPv4 and IPv6) * Download a PowerShell function to decompress the .tar.gz files into temporary folders * Loop through each country file and create a new Transport Rule (New-TransportRule) with country-specific IP ranges

You will end up with about 230 IPv4 and 230 IPv6 new Mail Flow Rules. All rules will be Disabled and All rules will be sorted last in priority. My intention is you use this script to Create new rules, but then logon to Office 365 > Exchange admin center > Mail Flow > Rules to Enable and change Priority for the newly-created rules that interest you. Optionally, my script should be easy enough to modify to also automate those tasks as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Use IPdeny country blocks to create Office 365 transport rules
 
# Connect to Office 365 Exchange
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication  Basic -AllowRedirection
Import-PSSession $Session
 
# Create a few Temporary Folders
$FolderRoot = "c:\temp\ipdeny"
$FolderDownloaded = "$FolderRoot\downloaded"
New-Item -Path $FolderRoot -ItemType directory
New-Item -Path $FolderDownloaded -ItemType directory
 
# Download IPdeny IPv4 file
$IPv4URL = "https://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz"
$IPv4Local = "$FolderDownloaded\ipv4-all-zones.tar.gz"
Invoke-WebRequest $IPv4URL -OutFile $IPv4Local
 
# Download IPdeny IPv6 file
$IPv6URL = "https://www.ipdeny.com/ipv6/ipaddresses/blocks/ipv6-all-zones.tar.gz"
$IPv6Local = "$FolderDownloaded\ipv6-all-zones.tar.gz"
Invoke-WebRequest $IPv6URL -OutFile $IPv6Local
 
# Load a function to enable .tar and .gz decompression
# Attribution https://stackoverflow.com/questions/38776137/native-tar-extraction-in-powershell
# Attribution https://www.powershellgallery.com/packages/7Zip4PowerShell/1.8.0
function Expand-Tar($tarFile, $dest) {
 
    if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
        Install-Package -Scope CurrentUser -Force 7Zip4PowerShell > $null
    }
 
    Expand-7Zip $tarFile $dest
}
 
# Decompress .gz files
Expand-7Zip "$FolderDownloaded\ipv4-all-zones.tar.gz" "$FolderDownloaded"
Expand-7Zip "$FolderDownloaded\ipv6-all-zones.tar.gz" "$FolderDownloaded"
 
# Decompress .tar files
Expand-7Zip "$FolderDownloaded\ipv4-all-zones.tar" "$FolderDownloaded\ipv4"
Expand-7Zip "$FolderDownloaded\ipv6-all-zones.tar" "$FolderDownloaded\ipv6"
 
# Delete .tar files
Remove-Item "$FolderDownloaded\ipv4-all-zones.tar"
Remove-Item "$FolderDownloaded\ipv6-all-zones.tar"
 
# Note new IPv4 and IPv6 folders
$IPv4Folder = "$FolderDownloaded\ipv4"
$IPv6Folder = "$FolderDownloaded\ipv6"
 
# Note new IPv4 and IPv6 files
$IPv4Files = Get-ChildItem $IPv4Folder
$IPv6Files = Get-ChildItem $IPv6Folder
 
# Uncomment if you want to test a smaller sample size
$IPv4Files = Get-ChildItem $IPv4Folder | Select -First 5
$IPv6Files = Get-ChildItem $IPv6Folder | Select -First 5
 
# Loop: Create an Office 365 Transport Rule to block IPv4 addresses for each country .zone file
foreach ($IPv4File in $IPv4Files) {
 
	# Null all previous variables
	$Comments = $null
	$CountIPs = $null
	$CountryName = $null
	$Date = $null
	$Enabled = $null 
	$Mode = $null
	$Name = $null
	$Quarantine = $null
	$RuleErrorAction = $null
	$SenderAddressLocation = $null
	$SenderIpRanges = $null
	$StopRuleProcessing = $null
 
	# Set fixed variables
	$Enabled = $False 
	$Mode = "Enforce"
	$Quarantine = $True
	$RuleErrorAction = "Ignore"
	$SenderAddressLocation = "Header"
	$StopRuleProcessing = $True
 
	# Set dynamic variables
	$Date = Get-Date
	$SenderIpRanges = Get-Content $FolderDownloaded\IPv4\$IPv4File
	$CountIPs = ($SenderIpRanges | Measure-Object).Count
	$Comments = "$CountIPs IPv4 country addresses imported from ipdeny.com ($Date)"
	$CountryName = $IPv4File.Name.Trim().ToUpper().Replace(".ZONE","")
	$Name = "Block-IPdeny-IPv4-$CountryName"
 
	# Report on screen
	Write-Host "----------------------------------------"
	Write-Host "       File:" $IPv4File.Name
	Write-Host "   Comments:" $Comments
	Write-Host "CountryName:" $CountryName
	Write-Host "       Name:" $Name
	Write-Host "NumberOfIPs:" $CountIPs
	Write-Host "IPv4 Ranges:" $SenderIpRanges
 
	# Remove existing rule (error will display if the rule does not exist, which is okay)
	Remove-TransportRule $Name -Confirm:$False
 
	# Create New Rule
	New-TransportRule -Comments $Comments -Enabled $Enabled -Mode $Mode -Name $Name -Quarantine $Quarantine -RuleErrorAction $RuleErrorAction -SenderAddressLocation $SenderAddressLocation -SenderIpRanges $SenderIpRanges -StopRuleProcessing $StopRuleProcessing
 
}
 
# Loop: Create an Office 365 Transport Rule to block IPv6 addresses for each country .zone file
foreach ($IPv6File in $IPv6Files) {
 
	# Null all previous variables
	$Comments = $null
	$CountIPs = $null
	$CountryName = $null
	$Date = $null
	$Enabled = $null 
	$Mode = $null
	$Name = $null
	$Quarantine = $null
	$RuleErrorAction = $null
	$SenderAddressLocation = $null
	$SenderIpRanges = $null
	$StopRuleProcessing = $null
 
	# Set fixed variables
	$Enabled = $False 
	$Mode = "Enforce"
	$Quarantine = $True
	$RuleErrorAction = "Ignore"
	$SenderAddressLocation = "Header"
	$StopRuleProcessing = $True
 
	# Set dynamic variables
	$Date = Get-Date
	$SenderIpRanges = Get-Content $FolderDownloaded\IPv6\$IPv6File
	$CountIPs = ($SenderIpRanges | Measure-Object).Count
	$Comments = "$CountIPs IPv6 country addresses imported from ipdeny.com ($Date)"
	$CountryName = $IPv6File.Name.Trim().ToUpper().Replace(".ZONE","")
	$Name = "Block-IPdeny-IPv6-$CountryName"
 
	# Report on screen
	Write-Host "----------------------------------------"
	Write-Host "       File:" $IPv6File.Name
	Write-Host "   Comments:" $Comments
	Write-Host "CountryName:" $CountryName
	Write-Host "       Name:" $Name
	Write-Host "NumberOfIPs:" $CountIPs
	Write-Host "IPv4 Ranges:" $SenderIpRanges
 
	# Remove existing rule (error will display if the rule does not exist, which is okay)
	Remove-TransportRule $Name -Confirm:$False
 
	# Create New Rule
	New-TransportRule -Comments $Comments -Enabled $Enabled -Mode $Mode -Name $Name -Quarantine $Quarantine -RuleErrorAction $RuleErrorAction -SenderAddressLocation $SenderAddressLocation -SenderIpRanges $SenderIpRanges -StopRuleProcessing $StopRuleProcessing
 
}

Screenshot of Result

The result in Office 365 > Exchange admin center > Mail Flow > Rules will look like this. Note that I imported only a few IPv4 and IPv6 rules (an option in my script). By default, my script will create about 460 new rules; two for each country (IPv4 and IPv6).

Note that all an Exchange Online admin has to do at this point is to Prioritize and Enable the rules for the countries they wish to block. Each rule is named by the country’s two-character abbreviation and each Rule Comment tells you how many IP blocks were imported and when.

You may re-run this script any time. It will delete existing Rules and create new ones with the updated data from IPdeny.

I hope someone finds this PowerShell script for Office 365 Exchange Online and IPdeny helpful.

My photos have been viewed 2,000,000 on Google Maps

I bought a 360 degree Ricoh Theta camera about a year ago. I’ve enjoyed using it to add 360 degree photos to user-contributed photos on Google Maps. Apparently, they are popular for I received this email from Google today:

You’re a top photographer on Google Maps. You’ve just accomplished what very few people have done: reached 2,000,000 photo views. Congratulations on the amazing accomplishment.

It’s nice to learn my images are helpful (or at least seen).