All users who have logged in to AD in the past x hours

This query grabs all the users who have a last logon timestamp shorter than 15 days ago and then for each of those users checks each of the Domain Controllers for the latest logon and reports the user if they have logged in in the past 8 hours.

$dcs = Get-ADDomainController -Filter *
$FileDate = [DateTime]::Now.AddDays(-15).ToFileTime()
Get-AdUser -filter {LastLogonTimestamp -gt $FileDate} | ForEach {
    $time = 0
    foreach($dc in $dcs)
    { 
        $user = Get-ADUser $_.Name -Server $dc.HostName -Properties lastLogon 
        if($user.LastLogon -gt $time) 
        {
            $time = $user.LastLogon
        }
    }
    $dt = [DateTime]::FromFileTime($time)
    If ($dt -gt [DateTime]::Now.AddHours(-8)) {"$($_.Name) last logged on at: $dt"}
}
Advertisements

Migrate FSRM Quotas using PowerShell to 2012 R2 – Simple Version

UPDATE 1.05
– Remove commas from size value
– Added handle for “The requested object was not found” result from dirquota.exe

UPDATE 1.04
– Updated code for folders that have no share path or multiple share paths

UPDATE 1.03
– Updated E-mail notification to handle ‘from’ field
– Updated notification section to handle empty notifications (threshold but no actions)

UPDATE: 1.02
– Added code to fix paths with dollar signs

UPDATE: 1.01
– Updated code to handle path not found if no quota exists.
– Updated example to include how to handle paths with dollar signs

This is an updated version of my previous script to migrate quotas from Windows 2008 R2 to Windows 2012 R2

Previous version that takes into account already applied auto quotas to limit the output to only quotas that need to be updated.

This version simply sets all of the quotas and ignores auto quotas. If you use auto quotas then the best method is the use the output from this script to duplicate the quotas then add the auto quotas manually afterwards.

This script makes the following assumptions,
1) The quota templates needed to be applied have been migrated to the new server. This is a native command using dirquota.exe template export /File:PATH
2) There are currently no quotas on the new server. All Auto Quotas are to be assigned after this scripts output has been run on the new server.
3) DIRQUOTA LIMITATION: Commands are set with a KillTimeOut of 10 minutes. You can change this manually in either the script or the output.
4) DIRQUOTA LIMITATION: dirquota.exe does not output if the Report ‘Files By Property’ so due to this it is assumed that this report is ticked on for all instances of report actions.

# Written by Ben Penney https://sysadminben.wordpress.com # Version 1.05 # This script has been written to be run on the old/source FSRM server and the output generated to be executed on the target server. # This script has been tested on 2008 R2 and 2012 R2 source servers and 2012 R2 target servers. # SourcePath is the local path on the old server of the folder you want to export the quotas from. # TargetPath is the local path on the new server where you will execute the generated PowerShell commands # Example: # .\ExportQuotas -SourcePath "O:\StaffShared" -TargetPath "C:\TEST" > ImportQuotas.ps1 # DOLLAR SIGNS IN PATH? - Don't forget to escape the dollar signs with a ` character Param([Parameter(Mandatory = $true)] $SourcePath,$TargetPath) Function processDirQuotaOutput ($QuotaOutput) { If ($QuotaOutput -like '*The specified path is invalid.*') {Return} If ($QuotaOutput -like "*not found*" -Or $QuotaOutput -like "*No quotas exist*") {Return} [int]$LineNum = 2 If ($QuotaOutput[1] -like 'This tool is deprecated*') {$LineNum += 2} # For 2012 output While ($LineNum -lt $QuotaOutput.Length) { # ---------- Quota Path Line ---------- $QuotaPath = $QuotaOutput[$LineNum].Substring(24,$QuotaOutput[$LineNum].Length-24) $QuotaPathNew = $($QuotaPath -iReplace(($SourcePath -replace "\\","\\" -replace "\$","\$"),$TargetPath)) $QuotaPathParent = $QuotaPath.SubString(0,$QuotaPath.LastIndexOf("\")) $LineNum++ # ---------- Share Path (2008) or Description (2012) Line ---------- # Skipped While ($QuotaOutput[$LineNum].Substring(0,15) -ne "Source Template") {$LineNum++} # ---------- Source Template Line ---------- If ($QuotaOutput[$LineNum] -like '*(Does not match template)') { $SourceTemplateMatches = $false $SourceTemplate = $QuotaOutput[$LineNum].Substring(24,$QuotaOutput[$LineNum].Length-50) } ElseIf ($QuotaOutput[$LineNum] -like '*(Matches template)') { $SourceTemplateMatches = $true $SourceTemplate = $QuotaOutput[$LineNum].Substring(24,$QuotaOutput[$LineNum].Length-43) } $LineNum++ # ---------- Quota Status Line ---------- If ($QuotaOutput[$LineNum] -like '*Disabled') {$QuotaStatus = "-Disabled "} $LineNum++ # ---------- Limit Line ---------- $Limit = $QuotaOutput[$LineNum].Substring(24,$QuotaOutput[$LineNum].Length-31).Replace(' ','').Replace(',','') If ($QuotaOutput[$LineNum].Substring($QuotaOutput[$LineNum].Length-5,4) -eq 'Soft') { $LimitType = "-SoftLimit" } $LineNum++ # ---------- Used, Available, Peak Usage Line ---------- # Skipped $LineNum += 3 # ---------- START: Generate Quota commands ---------- # Before thresholds line generate command to create quota $FRSMCommand = "New-FsrmQuota -Path '$QuotaPathNew' -Size $Limit $LimitType $QuotaStatus" If ($SourceTemplate -ne $Null) { $FRSMCommand += " -Template '$SourceTemplate'" } $FRSMCommand # ----------- END: Generate Quota commands ----------- # ---------- Thresholds Line ---------- $LineNum += 2 If ($QuotaOutput[$LineNum-2] -notlike '*None') { $Thresholds = "" While ($LineNum -lt $QuotaOutput.Length -And ` $QuotaOutput[$LineNum] -notlike 'Quota Path:*') { $Actions = "" [int]$NotificationLimit = $QuotaOutput[$LineNum].SubString($QuotaOutput[$LineNum].IndexOf("(")+1,3).Trim() $LineNum += 2 While ($LineNum -lt $QuotaOutput.Length -And ` $QuotaOutput[$LineNum] -notlike 'Quota Path:*' -And ` $QuotaOutput[$LineNum] -notlike 'Notifications for *') { $NotificationType = "Error" If ($QuotaOutput[$LineNum].Length -gt 32) {$NotificationType = $QuotaOutput[$LineNum].SubString(32,$QuotaOutput[$LineNum].Length-32)} Switch ($NotificationType) { 'Error' {$LineNum += 2} 'Event Log' { [int]$RunLimitInterval = $QuotaOutput[$LineNum+1].SubString(32,$QuotaOutput[$LineNum+1].Length-39) $EventType = $QuotaOutput[$LineNum+2].SubString(32,$QuotaOutput[$LineNum+2].Length-32) $MessageBody = $QuotaOutput[$LineNum+3].SubString(32,$QuotaOutput[$LineNum+3].Length-32) $LineNum += 5 While ($LineNum -lt $QuotaOutput.Length -And ` $QuotaOutput[$LineNum] -notlike 'Quota Path:*' -And ` $QuotaOutput[$LineNum] -notlike '*Notification Type:*' -And ` $QuotaOutput[$LineNum] -notlike 'Notifications for *') { $MessageBody += "`r`n" + $QuotaOutput[$LineNum-1] $LineNum++ } $Actions += ",(New-FsrmAction Event -EventType $EventType -Body '$MessageBody')" } 'E-mail' { [int]$RunLimitInterval = $QuotaOutput[$LineNum+1].SubString(32,$QuotaOutput[$LineNum+1].Length-39) $MailTo = $QuotaOutput[$LineNum+2].SubString(32,$QuotaOutput[$LineNum+2].Length-32) $LineNum += 3 $MailSubject = "" If ($QuotaOutput[$LineNum] -like '*Mail Subject:*') { $MailSubject = $QuotaOutput[$LineNum].SubString(32,$QuotaOutput[$LineNum].Length-32) $LineNum++ } If ($QuotaOutput[$LineNum] -like '*Mail From:*') {$LineNum++} $MessageBody = $QuotaOutput[$LineNum].SubString(32,$QuotaOutput[$LineNum].Length-32) $LineNum += 2 While ($LineNum -lt $QuotaOutput.Length -And ` $QuotaOutput[$LineNum] -notlike 'Quota Path:*' -And ` $QuotaOutput[$LineNum] -notlike '*Notification Type:*' -And ` $QuotaOutput[$LineNum] -notlike 'Notifications for *') { $MessageBody += "`r`n" + $QuotaOutput[$LineNum-1] $LineNum++ } $Actions += ",(New-FsrmAction Email -MailTo '$MailTo' -Subject '$MailSubject' -Body '$MessageBody'" $Actions += " -RunLimitInterval $RunLimitInterval)" } 'Command' { [int]$RunLimitInterval = $QuotaOutput[$LineNum+1].SubString(32,$QuotaOutput[$LineNum+1].Length-39) $Command = $QuotaOutput[$LineNum+2].SubString(32,$QuotaOutput[$LineNum+2].Length-32) $Arguments = $QuotaOutput[$LineNum+3].SubString(32,$QuotaOutput[$LineNum+3].Length-32) $WorkingDirectory = $QuotaOutput[$LineNum+4].SubString(32,$QuotaOutput[$LineNum+4].Length-32) Switch ($QuotaOutput[$LineNum+5].SubString(32,$QuotaOutput[$LineNum+5].Length-32)) { 'NT AUTHORITY\LOCAL SERVICE' {$RunAs = 'LocalService'} 'NT AUTHORITY\SYSTEM' {$RunAs = 'LocalSystem'} 'NT AUTHORITY\NETWORK SERVICE' {$RunAs = 'NetworkService'} } $LineNum += 7 $Actions += ",(New-FsrmAction Command -Command '$Command' -CommandParameters '$Arguments' -WorkingDirectory '$WorkingDirectory'" $Actions += " -SecurityLevel $RunAs -RunLimitInterval $RunLimitInterval -Killtimeout 10)" } 'Report' { #---Do nothing for now--- [int]$RunLimitInterval = $QuotaOutput[$LineNum+1].SubString(32,$QuotaOutput[$LineNum+1].Length-39) $LineNum += 2 $Reports = "FilesByProperty" While ($QuotaOutput[$LineNum] -notlike '*Reports saved to:*') { Switch ($QuotaOutput[$LineNum].SubString(6,10)) { 'Duplicate ' {$Reports += ",DuplicateFiles"} 'File Scree' {$Reports += ",FileScreen"} 'Files by F' {$Reports += ",FilesByFileGroup"} 'Files by O' {$Reports += ",FilesByOwner"} 'Large File' {$Reports += ",LargeFiles"} 'Least Rece' {$Reports += ",LeastRecentlyAccessed"} 'Most Recen' {$Reports += ",MostRecentlyAccessed"} 'Quota Usag' {$Reports += ",QuotaUsage"} } $LineNum++ } $SendReportsTo = "" If ($QuotaOutput[$LineNum+1].Length -gt 32) { $SendReportsTo = $QuotaOutput[$LineNum+1].SubString(32,$QuotaOutput[$LineNum+1].Length-32) } $LineNum += 3 $Actions += ",(New-FsrmAction Report -ReportTypes $Reports -MailTo '$SendReportsTo')" } } } If ($Actions -ne '') {$Thresholds += ",(New-FsrmQuotaThreshold -Percentage $NotificationLimit -Action $($Actions.SubString(1)))"} } If ($Thresholds -ne '') {"Set-FsrmQuota -Path '$QuotaPathNew' -Threshold $($Thresholds.SubString(1))"} } # ----------- END: Generate Threshold commands ----------- # ---------- START: Reset variables ---------- $QuotaPath = $null $QuotaPathNew = $null $QuotaPathParent = $null $SourceTemplate = $null $SourceTemplateMatches = $null $QuotaStatus = $null $Limit = $null $LimitType = $null # ----------- END: Reset variables ----------- } } # ---------- START: Process Quotas ---------- processDirQuotaOutput (dirquota quota list /path:$SourcePath\* -List-Notifications) processDirQuotaOutput (dirquota quota list /path:$SourcePath\ -List-Notifications) # ----------- END: Process Quotas -----------

Convert all group types in OU with Powershell

Using the following command will convert every group in that OU (and sub OUs unless you add the -SearchScope OneLevel switch) to type Distribution with Scope Global.

get-adgroup -filter * -SearchBase "OU=Groups,DC=work,DC=com" | ForEach {$x=[ADSI]"LDAP://CN=$($_.Name),OU=Groups,DC=work,DC=com"; $x.Put("groupType","2"); $x.setInfo()}

To change to the following group types/scopes use the following values for “groupType”,

Distribution – Universal = 8
Distribution – Domain Local = 4
Distribution – Global = 2

**STILL CANNOT GET THE FOLLOWING TO WORK**
Security – Universal = -2147483640
Security- Domain Local = -2147483644
Security- Global = -2147483646

Audit all users in Active Directory

This will output all users in the domain with their last login timestamp converted to dd/mm/yyyy format, creation date, and enabled value.

get-aduser -Filter * -Property whenCreated, LastLogonTimeStamp, AccountExpirationDate | Select Distinguishedname, whenCreated,@{Name='LastLogonTimestamp'; Expression={[DateTime]::FromFileTime($_.LastLogonTimestamp).ToString("dd/MM/yyyy")}}, AccountExpirationDate, Enabled | Export-CSV output.csv

Add the following switch to the get-aduser command to limit the search,

-SearchBase "OU=staff,ou=users,ou=business,dc=work,dc=com"

Add the following command to exclude any objects in the sub OU ‘Archive’,

| Where {$_.DistinguishedName -notlike '*Archive*'}

Add the following switch to get-aduser command to not search sub OUs,

-SearchScope OneLevel

Example below with all options,

get-aduser -filter * -SearchBase "OU=staff,ou=users,ou=business,dc=work,dc=com" -SearchScope OneLevel -Property whenCreated, LastLogonTimeStamp, AccountExpirationDate | Select Distinguishedname, whenCreated, @{Name='LastLogonTimestamp'; Expression={[DateTime]::FromFileTime($_.LastLogonTimestamp).ToString("dd/MM/yyyy")}}, AccountExpirationDate, Enabled | Export-CSV output.csv