Principais conclusões
- Monitoramento automatizado de usuários: Este script do PowerShell automatiza o monitoramento dos logins dos usuários em sistemas Windows.
- Cheques personalizáveis: Adapte o script para verificar usuários específicos ou qualquer usuário conectado.
- Integração do NinjaOne RMM com o: Integra-se ao NinjaOne RMM para oferecer maior personalização e melhor acesso aos dados.
- Eficiência operacional Garante que as contas de usuário necessárias estejam ativas para o funcionamento do aplicativo.
- Melhoria de segurança: Ajuda a manter a segurança por meio do monitoramento de acessos autorizados e não autorizados.
- Flexibilidade: Adapta-se a diferentes ambientes de execução por meio do gerenciamento de variáveis de ambiente.
- Alertas em tempo real: Fornece alertas imediatos com base no status de login do usuário.
- Compatibilidade: Compatível com o Windows 10 e o Windows Server 2012 R2 e versões posteriores.
- Fácil integração com o: Pode ser integrado às ferramentas de gerenciamento de TI existentes para um monitoramento coeso do sistema.
- Suporte à conformidade: Ajuda a garantir o cumprimento dos protocolos de segurança por meio do monitoramento das atividades dos usuários.
Contexto
O script fornecido é uma ferramenta do PowerShell projetada para profissionais de TI e provedores de serviços gerenciados (MSPs) da para monitorar os logins dos usuários em sistemas baseados no Windows. Sua relevância decorre da necessidade de garantir que determinadas contas de usuário estejam ativas ou de verificar se algum usuário está conectado, especialmente no caso de aplicativos legados que exigem sessões de usuário autenticadas. O script se destaca por suas opções de personalização e integração com o NinjaOne RMM, nossa plataforma de monitoramento e gerenciamento remoto .
O roteiro:
<#
.SYNOPSIS
Alert if no user is logged in, or if a specified user is not logged in. It can also accept a custom text field name to identify the user to check.
.DESCRIPTION
Alert if no user is logged in, or if a specified user is not logged in. It can also accept a custom text field name to identify the user to check.
Intended for legacy apps that are non-functional without an actual user account signed in.
.EXAMPLE
(No Parameters)
itAdmin alternateAdmin tuser is currently signed in!
PARAMETER: -CheckUser "itAdmin"
Enter in the user you'd like to alert on. ex. to alert on user itAdmin use -CheckUser "itAdmin"
.EXAMPLE
-CheckUser "itAdmin"
itAdmin is currently signed in!
PARAMETER: -CustomFieldName "ReplaceMeWithAnyTextCustomField"
The name of a text custom field to grab the CheckUser value from.
.EXAMPLE
-CustomFieldName "ReplaceMeWithAnyTextCustomField"
itAdmin is currently signed in!
.OUTPUTS
None
.NOTES
Minimum OS Architecture Supported: Windows 10, Windows Server 2012 R2
Release Notes: Renamed script and added Script Variable support
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider.
Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>
[CmdletBinding()]
param (
[Parameter()]
[Switch]$ActiveOnly = [System.Convert]::ToBoolean($env:userMustBeActive),
[Parameter()]
[String]$CheckUser,
[Parameter()]
[String]$CustomFieldName
)
begin {
# If script variables are used overwrite the existing variables.
if ($env:userToCheckFor -and $env:userToCheckFor -notlike "null") { $CheckUser = $env:userToCheckFor }
if ($env:retrieveUserFromCustomFieldName -and $env:retrieveUserFromCustomFieldName -notlike "null") { $CustomFieldName = $env:retrieveUserFromCustomFieldName }
# This function is to make it easier to parse Ninja Custom Fields.
function Get-NinjaProperty {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[String]$Name,
[Parameter()]
[String]$Type,
[Parameter()]
[String]$DocumentName
)
if($PSVersionTable.PSVersion.Major -lt 3){
throw "PowerShell 3.0 or higher is required to retrieve data from custom fields. https://ninjarmm.zendesk.com/hc/en-us/articles/4405408656013"
}
# If we're requested to get the field value from a Ninja document we'll specify it here.
$DocumentationParams = @{}
if ($DocumentName) { $DocumentationParams["DocumentName"] = $DocumentName }
# These two types require more information to parse.
$NeedsOptions = "DropDown","MultiSelect"
# Grabbing document values requires a slightly different command.
if ($DocumentName) {
# Secure fields are only readable when they're a device custom field
if ($Type -Like "Secure") { throw "$Type is an invalid type! Please check here for valid types. https://ninjarmm.zendesk.com/hc/en-us/articles/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality" }
# We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.
Write-Host "Retrieving value from Ninja Document..."
$NinjaPropertyValue = Ninja-Property-Docs-Get -AttributeName $Name @DocumentationParams 2>&1
# Certain fields require more information to parse.
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2>&1
}
}
else {
# We'll redirect error output to the success stream to make it easier to error out if nothing was found or something else went wrong.
$NinjaPropertyValue = Ninja-Property-Get -Name $Name 2>&1
# Certain fields require more information to parse.
if ($NeedsOptions -contains $Type) {
$NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2>&1
}
}
# If we received some sort of error it should have an exception property and we'll exit the function with that error information.
if ($NinjaPropertyValue.Exception) { throw $NinjaPropertyValue }
if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }
# This switch will compare the type given with the quoted string. If it matches, it'll parse it further; otherwise, the default option will be selected.
switch ($Type) {
"Attachment" {
# Attachments come in a JSON format this will convert it into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Checkbox" {
# Checkbox's come in as a string representing an integer. We'll need to cast that string into an integer and then convert it to a more traditional boolean.
[System.Convert]::ToBoolean([int]$NinjaPropertyValue)
}
"Date or Date Time" {
# In Ninja Date and Date/Time fields are in Unix Epoch time in the UTC timezone the below should convert it into local time as a datetime object.
$UnixTimeStamp = $NinjaPropertyValue
$UTC = (Get-Date "1970-01-01 00:00:00").AddSeconds($UnixTimeStamp)
$TimeZone = [TimeZoneInfo]::Local
[TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)
}
"Decimal" {
# In ninja decimals are strings that represent a decimal this will cast it into a double data type.
[double]$NinjaPropertyValue
}
"Device Dropdown" {
# Device Drop-Downs Fields come in a JSON format this will convert it into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Device MultiSelect" {
# Device Multi-Select Fields come in a JSON format this will convert it into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Dropdown" {
# Drop-Down custom fields come in as a comma-separated list of GUIDs; we'll compare these with all the options and return just the option values selected instead of a GUID.
$Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
$Options | Where-Object { $_.GUID -eq $NinjaPropertyValue } | Select-Object -ExpandProperty Name
}
"Integer" {
# Cast's the Ninja provided string into an integer.
[int]$NinjaPropertyValue
}
"MultiSelect" {
# Multi-Select custom fields come in as a comma-separated list of GUID's we'll compare these with all the options and return just the option values selected instead of a guid.
$Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header "GUID", "Name"
$Selection = ($NinjaPropertyValue -split ',').trim()
foreach ($Item in $Selection) {
$Options | Where-Object { $_.GUID -eq $Item } | Select-Object -ExpandProperty Name
}
}
"Organization Dropdown" {
# Turns the Ninja provided JSON into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization Location Dropdown" {
# Turns the Ninja provided JSON into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization Location MultiSelect" {
# Turns the Ninja provided JSON into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Organization MultiSelect" {
# Turns the Ninja provided JSON into a PowerShell Object.
$NinjaPropertyValue | ConvertFrom-Json
}
"Time" {
# Time fields are given as a number of seconds starting from midnight. This will convert it into a datetime object.
$Seconds = $NinjaPropertyValue
$UTC = ([timespan]::fromseconds($Seconds)).ToString("hh\:mm\:ss")
$TimeZone = [TimeZoneInfo]::Local
$ConvertedTime = [TimeZoneInfo]::ConvertTimeFromUtc($UTC, $TimeZone)
Get-Date $ConvertedTime -DisplayHint Time
}
default {
# If no type was given or not one that matches the above types just output what we retrieved.
$NinjaPropertyValue
}
}
}
function Get-User {
$quser = quser.exe
$quser -replace '\s{2,}', ',' -replace '>' | ConvertFrom-Csv
}
}process {
# If a custom field name is provided grab the text and overwrite the $CheckUser variable with it.
if ($CustomFieldName) {
if (-not ($CheckUser)) {
try{
$CheckUser = Get-NinjaProperty -Name $CustomFieldName
}catch{
Write-Warning "$($_.ToString())"
}
if(-not $CheckUser){
Write-Warning "The custom field $CustomFieldName was empty!"
}
}
}
if($CheckUser){
Write-Host "Checking for $CheckUser."
}else{
Write-Host "Checking if any user is logged in."
}
# This will work whether or not your looking for any user to be logged in ($CheckUser = $null) or a specific one.
$LoggedInUsers = Get-User
if ($ActiveOnly) {
$Test = $LoggedInUsers | Where-Object { $_.USERNAME -match $CheckUser } | Where-Object { $_.STATE -like "Active" }
}
else {
$Test = $LoggedInUsers | Where-Object { $_.USERNAME -match $CheckUser }
}
# If we didn't find the user or users we were looking for error out and exit 1
if (!$Test) {
Write-Error "The user(s) you are checking for is not currently logged in!"
$LoggedInUsers | Format-Table USERNAME, STATE, "LOGON TIME", SESSIONNAME | Out-String | Write-Host
exit 1
}
else {
# Otherwise exit 0
Write-Host "$($LoggedInUsers.USERNAME) is currently signed in!"
$LoggedInUsers | Format-Table USERNAME, STATE, "LOGON TIME", SESSIONNAME | Out-String | Write-Host
exit 0
}
}end {
}
Acesse mais de 300 scripts no NinjaOne Dojo
Discriminação detalhada
O script funciona em várias etapas:
- e de inicialização: Começa definindo parâmetros que controlam seu comportamento, como verificar apenas usuários ativos ou focar em um usuário específico.
- Tratamento de variáveis de ambiente: Ele verifica se há variáveis de ambiente que possam substituir seus parâmetros, garantindo a adaptabilidade em diferentes ambientes de execução.
- Recuperação de campos personalizados: O script pode obter informações do usuário a partir de campos personalizados definidos, proporcionando flexibilidade na obtenção de dados de login.
- Recuperação de login do usuário: Ao utilizar o comando ` quser `, ele recupera a lista de usuários conectados, uma funcionalidade essencial do script.
- Verificação e alerta de usuário: Dependendo dos parâmetros definidos, o script verifica se há algum usuário conectado ou um usuário específico e emite o alerta correspondente.
Possíveis casos de uso
Imagine um administrador de TI responsável por uma rede na qual determinados aplicativos exigem que um usuário administrador permaneça conectado o tempo todo. Com esse script, eles podem configurar verificações automatizadas para garantir que as contas de usuário necessárias estejam ativas, mantendo assim a funcionalidade do aplicativo e a segurança do sistema.
Comparações
Os métodos tradicionais de monitoramento do login de usuários podem envolver verificações manuais ou scripts básicos, sem opções de personalização. Este script do PowerShell supera esses métodos graças à sua integração com o NinjaOne RMM, à sua personalização e aos recursos de alertas automáticos.
Implicações
A capacidade do script de monitorar os logins dos usuários é fundamental para manter os protocolos de segurança, garantir a conformidade e impedir o acesso não autorizado. Além disso, auxilia na resolução de problemas e na manutenção operacional, fornecendo dados de login dos usuários em tempo real.
Recomendações
- Atualize o script regularmente para acompanhar as atualizações do sistema.
- Personalize os parâmetros do script de acordo com as necessidades específicas do ambiente de TI.
- Integre o script às ferramentas de gerenciamento de TI existentes para obter uma abordagem de monitoramento coesa.
Considerações finais
A incorporação desse script do PowerShell à sua infraestrutura de TI, especialmente quando combinado com o NinjaOne, aumenta sua capacidade de monitorar os logins dos usuários de maneira eficaz. A plataforma da NinjaOne oferece uma camada adicional de gerenciamento e segurança, tornando o script um elemento indispensável de uma estratégia abrangente de gerenciamento de TI.