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"

Is Roger Ver claiming he is Bitcoin’s founder Satoshi Nakamoto?

On June 27, 2018, the People’s Labour Party, a political party in Saint Kitts and Nevis led by the country’s prime minister Timothy Harris, posted the following on Twitter:

The first #Bitcoin ATM Machine in the Caribbean has just been installed in #StKitts. There will be 4 Machines across the island with the first one installed by Bitcoin Founder @rogerkver and associate Alex Lewis at the “The Mill” Cafe at the Oceans Edge Development in Frigate Bay

There are many inaccuracies with this tweet. The most egregious, however, is that Roger Ver convinced Saint KittsPeoples Labour Party that he is Bitcoin‘s Founder Satoshi Nakamoto.

In August 2017, Roger Ver performed a hard fork of Bitcoin (BTC) by copying all of its code and blockchain history to form his own separate, alternative, and centralized coin called Bitcoin Cash (BCH).

Bitcoin’s code is open source, so there’s nothing wrong with copying its code to make your own coin. But Ver has frequently made claims that his coin, Bitcoin Cash (BCH), is the real Bitcoin (BTC) when it is not.

It now appears that Ver’s ability to confuse people about who he is and the cryptocurreny he represents has escalated — for Roger Ver has convinced a small country’s political party that he is Bitcoin’s founder Satoshi Nakamoto.

While I cannot disprove that Roger Ver is not Satoshi Nakamoto, it is unlikely that he is.

What I can point out are some of the fallacies of the above tweet:

  • Bitcoin ATM (incorrect): What was deployed, as stated by Roger Ver in the video of him standing next to the ATM, was a Bitcoin Cash ATM. If the People’s Labour Party thinks that Saint Kitts received four Bitcoin ATMs; then they were conned by Roger Ver, who says on video that they are Bitcoin Cash ATMs.
  • First Bitcoin ATM in the Caribbean (incorrect): According to Coin ATM Radar, Bitcoin ATMs already exist in Anguilla, Aruba, Barbados, Dominica Republic, and Jamaica; all of which are Caribbean countries. This may be, however, the first Bitcoin Cash ATM in the Caribbean.
  • Bitcoin Founder Roger Ver (likely incorrect): It is unlikely that Roger Ver is Bitcoin’s founder Satoshi Nakamoto. If he isn’t, he shouldn’t be convincing political parties or anyone else that he is.

As for the People’s Labour Party and citizens of Saint Kitts, it appears they were tricked into thinking they were getting Bitcoin ATMs delivered to them personally by Bitcoin’s founder. Instead, they received four Bitcoin Cash ATMs delivered to them by Roger Ver, the founder of Bitcoin Cash (not Bitcoin).

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.

Unwanted solicitation from Ryan Tello of Rydek Professional Staffing

I received an unpleasant solicitation from Ryan Tello today, the Vice President of Client Development for Rydek Professional Staffing out of Corona, California.

The unwanted phone call began as normal. Ryan gave a two- to four-minute pitch introducing himself, his company, and service. While these unwanted solicitations are tiresome and ignore my publicly posted request for privacy; Ryan Tello was both normal and polite during the early stages of the call.

I responded by saying “No thank you;” but Ryan wasn’t ready to give up and began asking for reasons why. When I said “Honestly, I avoid doing business with companies that perform cold calls and cold emails (as stated in my Privacy Policy),” he became upset and reacted poorly.

Ryan started with the typical “How will you learn about my product or service?” and similar questions already addressed in my Do Not Solicit FAQ. He then wanted to know my job title and responsibilities, which I replied, “I’m sorry, we do not discuss job titles, responsibilities, or system infrastructure with unsolicited callers.”

My reason is that there is no easy way to distinguish a sales call from a social engineering attack — both are initiated by the potential bad actor and both are an attempt to learn more about a company, individual, system, or process.

That’s when Ryan Tello began his ad hominem attack, stating that I must be a terrible person to work for. I asked him to please don’t call again. He said that he would keep calling — often — and will keep asking for different employees until someone speaks with him.

Ryan,

I politely said that I was not interested in your company or services, that I avoid doing business with companies that cold call and cold email, and that I would not answer your questions. You responded with personal attacks, followed by threats that you will keep calling and harassing other employees. Please don’t. You are the bad actor here. You ignored my request for privacy and threatened to harass my coworkers in the future.

I’ve warned my coworkers of your behavior and intentions. I further hope that his blog post may warn others of your potential irrational behavior and personal attacks.

Please don’t solicit me or my coworkers again. May this post serve as an additional Do Not Solicit and Opt Out request to you and your employer. Thank you.

Company: Rydek Professional Staffing
Company President: Adam Reinhardt
VP of Client Development: Ryan Tello

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.