Search code examples
powershellsubstring

How to select a substring in select/group command- Powershell


In the code below, the userprinciplename will output strings like "LLL_John.Smith@email.com" and XXXX_Jane.Doe@email.com" but i am hoping to extract a substring from that, that being the codes before the "_" character, so LLL and XXXX.

There may be some which do not have an underscore character however and so these would need to be ignored / have the original string it would have returned.

##Check bottom of script for setting specific OU
Function Get-LastLogon {
  param(
    [string]$OUName
  )

  # Get all matching OUs on any level
  $OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
  $DCs = Get-ADDomainController -Filter *

  # Get all users from each OU from each DC
  $ADUsers = Foreach ($OU in $OUs) {
    Foreach ($DC in $DCs.HostName) {
      Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties LastLogon -server $dc | 
        Select-Object Name,userPrincipalName, @{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}
    }
  }

  # return most recent LastLogon date for each user
  $ADUsers | 
    Group Name,userPrincipalName | 
    Select Name,userprinciplename, @{n='LastLogon';e={$_.Group.LastLogon | sort -desc | select -First 1}}
}  ## End function


##Enter the OU here
Get-LastLogon -OUName 'Clients' 

##Un-comment below to export to csv
## | Export-Csv -Path 'C:\temp\UserExport.csv'

Here is what the script looks like now in full:

##Check bottom of script for setting specific OU
Function Get-LastLogon {
  param(
    [string]$OUName
  )

  # Get all matching OUs on any level
  $OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
  $DCs = Get-ADDomainController -Filter *

$ADUsers = foreach ($OU in $OUs) {
    foreach ($dc in $DCs.HostName) {
        Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties lastLogonTimeStamp -Server $dc | 
            Select-Object Name,UserPrincipalName, 
                          @{Name = 'LastLogon';Expression = {[DateTime]::FromFileTime($_.lastLogonTimeStamp)}},
                          @{Name = 'UserCode'; Expression = {([regex]'^([^_]+)_.*').Match($_.UserPrincipalName).Groups[1].Value}}
        }
    }  }

# return the most recent LastLogon date for each user 
# (only the users with a code prefix in the UserPrincipalName)
$ADUsers | Where-Object { ![string]::IsNullOrWhiteSpace($_.UserCode) } |
    Group-Object UserPrincipalName | ForEach-Object {
        [PsCustomObject]@{
            Name      = $_.Group[0].Name
            UserCode  = $_.Group[0].UserCode
            LastLogon = $_.Group.LastLogon | Sort-Object -Descending | Select-Object -First 1
        }
    }
  ## End function

$OUcustom = Read-Host -prompt 'Enter OU here or "Clients" for all'
##Enter the OU here
Get-LastLogon -OUName $OUcustom |
##export csv
Export-Csv -path "C:\temp\UserExport_$((Get-Date).ToString("ddMM_HHmm")).csv" -NoTypeInformation
".csv extracted to C:\temp"
pause


Solution

  • So this was actually more simple than I realised. I just needed to add in:

    @{N='userPrincipalName';E={$_.userPrincipalName.Split("_")[0]}}
    

    To the first and second blocks where UserPrincipleName was being selected. Will post the full working code below for relevance.

    ##Check bottom of script for setting specific OU
    Function Get-LastLogon {
      param(
        [string]$OUName
      )
    
      # Get all matching OUs on any level
      $OUs = Get-ADOrganizationalUnit -Filter "Name -like '$OUName'"
      $DCs = Get-ADDomainController -Filter *
    
      # Get all users from each OU from each DC
      $ADUsers = Foreach ($OU in $OUs) {
        Foreach ($DC in $DCs.HostName) {
          Get-ADUser -SearchBase $OU.DistinguishedName -Filter * -Properties LastLogon -server $dc | 
            Select-Object Name,@{N='userPrincipalName';E={$_.userPrincipalName.Split("_")[0]}}, @{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}
        }
      }
    
      # return most recent LastLogon date for each user
      $ADUsers | 
        Group Name,userPrincipalName | 
        Select Name,@{N='userprinciplename';E={$_.userprinciplename.Split("_")[0]}}, @{n='LastLogon';e={$_.Group.LastLogon | sort -desc | select -First 1}}
    }  ## End function
    
    $OUcustom = Read-Host -prompt 'Enter OU here or "Clients" for all'
    ##Enter the OU here
    Get-LastLogon -OUName $OUcustom |
    ##export csv
    Export-Csv -path "C:\temp\UserExport_$((Get-Date).ToString("ddMM_HHmm")).csv" -NoTypeInformation
    ".csv extracted to C:\temp"
    
    pause