1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Powershell scripts you cant live without

Discussion in 'Servers and Enterprise Solutions' started by LizardKing, May 19, 2017.

  1. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    Thought i'd share some of the scripts that i've found pretty much invaluable over the years, feel free to add any you may use yourself and perhaps we can create a nice little repo :) (any code comments and an origonal source are a bonus!)

    1st off, quite a simple one, if you have a hybrid environment and fed up of waiting for a natural sync.

    Code:
    $SyncServer = "YourFedServer"
    $SyncServerSession = New-PSSession -ComputerName $SyncServer -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
    Invoke-Command -Session $SyncServerSession -ScriptBlock {Start-ADSyncSyncCycle -PolicyType Delta}
    Get-PSSession | Where-Object {$PSItem.ComputerName -eq $SyncServer} | Remove-PSSession
    
     
    Last edited: May 19, 2017
  2. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    2nd one is actually from our provisioning process when installing from a USB stick, we run it as a 1st run command as part of installing Windows

    Amend the 1st 2 lines to suit your environment, it will pop up a box asking for the computer name then your credentials and will join it to the domain in the ou you specify.

    Code:
    $ou = "OU=computers,DC=domain,DC=name"
    $domain = "domain.name"
    
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
    $computer = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the computer name", "Computer", "$env:computername")
    Add-Computer -domainname $domain -OUpath $ou -credential (get-credential) -NewName $computer
    
    
     
  3. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    A simple little one liner to show locked out users
    Code:
    Search-ADAccount -Locked | Select Name, LockedOut, LastLogonDate
    
    Then if you want to unlock all the accounts
    Code:
    Search-ADAccount -Locked | Select Name, LockedOut, LastLogonDate | Unlock-ADaccount
    
    If i get time i'll sanitize a few of my bigger ones later on today
     
  4. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    Heres our password reminder emails, we have a few users that are email only users so quite handy for them to get a reminder when there passwords are due to expire
    I cant remember where i got the original from unfortunately. this has been updated slightly from the original to make it a bit nicer
    The first 3 lines need editing to suit. if you want to test it without firing off emails to everyone thats meets the criteria change the following line
    Code:
    $smtpTo = "$useremail"
    to something like
    Code:
     $smtpTo = "youremail@compname.com" 
    Code:
    $ADResults = Get-ADUser -SearchBase "DC=domain,DC=name" -Filter {(Enabled -eq $True) -and (EmailAddress -like "*")} -Properties EmailAddress, PasswordExpired, PasswordNeverExpires, PasswordLastSet
    $smtpServer = "YourSMTPserver"
    $smtpFrom = "Support<support@yourcomp.com>"
    
    # LOOP THROUGH USERS IN ACTIVE DIRECTORY
    foreach ($user in $ADResults){
      $name = $user.Name
      $passwordlastset = $user.PasswordLastSet
      $passwordexpired = $user.PasswordExpired
      $passwordneverexpires = $user.PasswordNeverExpires
      $useremail = $user.EmailAddress
    
        # CALCULATE TIME BEFORE PASSWORD EXPIRATION
        #if your password has not expired and your password is not set to never expire and your password is not new
        if (($passwordexpired -ne $True) -and ($passwordneverexpires -ne $True) -and ($passwordlastset -ne $null)){
            $user_enddate = $passwordlastset + ((Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.TotalDays)
            $DaysLeft = (New-TimeSpan -Start (Get-Date) -End $user_enddate).Days
        # NOTIFY USER IF PASSWORD IS EXPIRING WITHIN 2 WEEKS
            if ($DaysLeft -le "9"){
    
    #### Header details to make the email nicer
    $Header = "<style>"
    $Header = $Header + "BODY{background-color:white;}"
    $Header = $Header + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
    $Header = $Header + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:#CB5DB3}"
    $Header = $Header + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:lightgrey}"
    $Header = $Header + "</style>"
    #### Body
    $b = "
    <font face='calibri' size='3'>
    Dear $name <br>
    Your password is due to expire in $DaysLeft day(s)!<br>
    If you do not change your password before it expires, you will be unable to access your email and/or computer.<br><br>
    <strong>Ways you can change your password.</strong><br>
    On your work desktop/laptop -&nbsp; press ctrl/alt del (if you're a remote worker ensure the vpn is connected first) <br>
    The webmail portal.&nbsp;<a title='Webmail Portal' href='https://portal.office.com/account/'>Link</a> - Follow the link to Security &amp; Privacy and there will be a link there to change it. <em>(Note - The Safari browser does not support this)</em><br><br>
    <strong>Dont forget to also update any devices (mobiles etc) that you use to access your emails.</strong><br><br>
    If you need futher assistance you can contact IT support via<br>
    01234 123456<br>
    Email - <a href='mailto:support@yourcomp.com'>support@yourcomp.com</a><br><br>
    Thank you<br>
    Support<br><br>
    </font>
    <em>This e-mail was automatically generated</em>
    "
    
    $body = ConvertTo-HTML -head $a -body $b
    
    
    
    $smtpTo = "$useremail"
    
    $messageSubject = "Your password is due to expire in $DaysLeft days"
    $message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
    $message.Subject = $messageSubject 
    $message.Body = $body
    If ($DaysLeft -lt 3) {
    $message.Priority = "High"
    }
    $message.IsBodyHTML = $true
    $smtp = New-Object Net.Mail.SmtpClient($smtpServer)
    $smtp.Send($message)
    }
    }
    }
    
    
     
  5. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    Another little one liner,

    This will search your o365 tennent for any disabled users with a license. (you will need to be connected to your tenant first)
    Code:
    get-aduser -filter {enabled -eq 'false' -and userprincipalname -ne "*"} -SearchBase "$TargetOU" | get-msoluser | where {$_.isLicensed -eq $true}
     
  6. traveyb

    Wise Guy

    Joined: Jul 25, 2012

    Posts: 1,233

    That password one is awesome, very nice thanks. Will dig out some of my scripts and post them up
     
  7. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    Its such a simple idea yet has saved quite alot of the helpdesks time. Unfortunately you still get people who don't read and end up getting locked out.

    Another invaluable powershell script that cleans our your wsus server fair better than its built in application.
    http://www.adamj.org/clean-wsus.html

    And courtesy of a Reddit/powershell poster a very easy to use GUI builder
    https://poshgui.com/
     
  8. Spammeh

    Hitman

    Joined: Aug 2, 2005

    Posts: 551

    These aren't all my own, and they are rather simple, but useful non-the-less

    User account disable script
    Code:
    
    Import-Module ActiveDirectory
     
    function Get-ADUsersLastLogon()
    {
     
      ################## Variables #####################
     
      # Number of days since user account object hasn't logged on to the domain
      $numberOfDays = (Get-Date).AddDays(-430)
     
      # Location of CSV output
      $logPath = "c:\DisabledUsers.csv"
    
      # OU that you wish to search for user accounts
      $searchbase = "DC=domain,DC=com"
    
      # OU that disabled accounts will be moved to
      $DisabledOU = "OU=Disabled Objects,DC=domain,DC=com"
     
      # Variables required to export to .csv
      $logDate = Get-Date -F dd-MM-yyyy
      $logArray = @()
    
      # Lookup to find domain controllers
      $dcs = Get-ADDomainController -Filter {Name -like "*"}
    
      # Search looking for user accounts older than $numberOfDays and accounts that are enabled
      $users = Get-ADUser -searchbase $SearchBase -Filter {((lastlogondate -le $numberOfDays) -AND (enabled -eq $True))}
     
      $time = 0
    
      # EMail variables
     
      $smtpServer = "SMTP"
      $smtpFrom = "email@company.com"
      $smtpTo = "user@company.com"
      $messageSubject = "$logDate - User Accounts Disabled"
      $messageBody = "Attached is a .csv containing the latest list of disabled user accounts, correct as of $logDate. Added this run: $logArray"
     
     
      ################# Script Body ####################
     
      foreach($user in $users)
      {
        #compares currentUser last logon time on each domain controller
        foreach($dc in $dcs)
        {
          $hostname = $dc.HostName
          $currentUser = Get-ADUser $user.SamAccountName | Get-ADObject -Server $hostname -Properties lastLogon
     
          if($currentUser.LastLogon -gt $time)
          {
            $time = $currentUser.LastLogon
          }
        }
        $time = 0
    
        # Disables user object
        Disable-ADAccount $currentUser
    
        # Adds description to user object description
        Set-ADUser $currentUser -Description "Account disabled on $logDate"
    
        # Moves user object to target OU
        Move-ADObject $currentUser -TargetPath $DisabledOU
     
        #Create array for logfile output
        $obj = $currentUser | Select Name,distinguishedname,@{n="status";e={'Disabled User'}},@{n="date disabled";e={$logdate}}
    
        #Output to Log
        $logArray += $obj
    
      }
        #Export contents of logArray to .csv
        $logArray | Export-Csv $logPath -NoTypeInformation -Append
    
        #Email Output
        Send-MailMessage -To $smtpTo -From $smtpFrom -Subject $messageSubject -Body $messageBody -Attachments $logPath -SmtpServer $smtpServer
    }
     
     # Run Function
     Get-ADUsersLastLogon
    Veeam Free Backup script
    Code:
    # VM names separated by commas
    $VMNames = “VM1”, “VM1”
    # vCenter name/IP
    $HostName = “10.30.10.140”
    # Directory that VM backups should go to
    $Directory = “\\10.30.10.85\Veeam”
    # Desired compression level, following compression level from Veeam (Optional)
    $CompressionLevel = “4”
    # Quiesce VM when taking snapshot (Optional; VMware Tools are required; Possible values: $True/$False)
    $EnableQuiescence = $True
    # Protect resulting backup with encryption key (Optional; $True/$False)
    $EnableEncryption = $False
    # Encryption Key (Optional; path to a secure string, C:\SecureString.txt”
    $EncryptionKey = “”
    # Retention settings (Optional; By default, VeeamZIP files are not removed and kept in the specified location for an indefinite period of time.
    # Possible values: Never , Tonight, TomorrowNight, In3days, In1Week, In2Weeks, In1Month)
    $Retention = “In3days”
    # Email Settings
    # Enable notification (Optional)
    $EnableNotification = $True
    # Email SMTP server
    $SMTPServer = “smtp.smtp.com”
    # Email FROM
    $EmailFrom = “sender@cnwr.com”
    # Email TO
    $EmailTo = “recipient@cnwr.com”
    # Email subject
    $EmailSubject = “Veeam Backup Job”
    # Email formatting
    $style = “<style>BODY{font-family: Arial; font-size: 10pt;}”
    $style = $style + “TABLE{border: 1px solid black; border-collapse: collapse;}”
    $style = $style + “TH{border: 1px solid black; background: #54b948; padding: 5px; }”
    $style = $style + “TD{border: 1px solid black; padding: 5px; }”
    $style = $style + “</style>”
    ##################################################################
    # End User Defined Variables
    ##################################################################
    #################### DO NOT MODIFY PAST THIS LINE ################
    Asnp VeeamPSSnapin
    $Server = Get-VBRServer -name $HostName
    $mbody = @()
    foreach ($VMName in $VMNames)
    {
    $VM = Find-VBRViEntity -Name $VMName -Server $Server
    $ZIPSession = Start-VBRZip -Entity $VM -Folder $Directory -Compression $CompressionLevel -DisableQuiesce:(!$EnableQuiescence) -AutoDelete $Retention
    If ($EnableNotification)
    {
    $TaskSessions = $ZIPSession.GetTaskSessions()
    $FailedSessions = $TaskSessions | where {$_.status -eq “EWarning” -or $_.Status -eq “EFailed”}
    if ($FailedSessions -ne $Null)
    {
    $mbody = $mbody + ($ZIPSession | Select-Object @{n=”Name”;e={($_.name).Substring(0, $_.name.LastIndexOf(“(“))}} ,@{n=”Start Time”;e={$_.CreationTime}},@{n=”End Time”;e={$_.EndTime}},Result,@{n=”Details”;e={$FailedSessions.Title}})
    }
    Else
    {
    $mbody = $mbody + ($ZIPSession | Select-Object @{n=”Name”;e={($_.name).Substring(0, $_.name.LastIndexOf(“(“))}} ,@{n=”Start Time”;e={$_.CreationTime}},@{n=”End Time”;e={$_.EndTime}},Result,@{n=”Details”;e={($TaskSessions | sort creationtime -Descending | select -first 1).Title}})
    }
    }
    }
    If ($EnableNotification)
    {
    $Message = New-Object System.Net.Mail.MailMessage $EmailFrom, $EmailTo
    $Message.Subject = $EmailSubject
    $Message.IsBodyHTML = $True
    $message.Body = $mbody | ConvertTo-Html -head $style | Out-String
    $SMTP = New-Object Net.Mail.SmtpClient($SMTPServer)
    $SMTP.Send($Message)
    }
    VMware Snapshot reminder:

    Code:
    # - SnapReminder V1.0 By Virtu-Al - http://virtu-al.net
    #
    # Please use the below variables to define your settings before use
    #
    $smtpServer = "mysmtpserver.mydomain.com"
    $MailFrom = "me@mydomain.com"
    $VISRV = "MYVISERVER"
     
    function Find-User ($username){
       if ($username -ne $null)
       {
          $usr = (($username.split("\"))[1])
          $root = [ADSI]""
          $filter = ("(&(objectCategory=user)(samAccountName=$Usr))")
          $ds = new-object system.DirectoryServices.DirectorySearcher($root,$filter)
          $ds.PageSize = 1000
          $ds.FindOne()
       }
    }
     
    function Get-SnapshotTree{
       param($tree, $target)
     
       $found = $null
       foreach($elem in $tree){
          if($elem.Snapshot.Value -eq $target.Value){
             $found = $elem
             continue
          }
       }
       if($found -eq $null -and $elem.ChildSnapshotList -ne $null){
          $found = Get-SnapshotTree $elem.ChildSnapshotList $target
       }
     
       return $found
    }
     
    function Get-SnapshotExtra ($snap){
       $guestName = $snap.VM   # The name of the guest
     
       $tasknumber = 999    # Windowsize of the Task collector
     
       $taskMgr = Get-View TaskManager
     
       # Create hash table. Each entry is a create snapshot task
       $report = @{}
     
       $filter = New-Object VMware.Vim.TaskFilterSpec
       $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
       $filter.Time.beginTime = (($snap.Created).AddSeconds(-5))
       $filter.Time.timeType = "startedTime"
     
       $collectionImpl = Get-View ($taskMgr.CreateCollectorForTasks($filter))
     
       $dummy = $collectionImpl.RewindCollector
       $collection = $collectionImpl.ReadNextTasks($tasknumber)
       while($collection -ne $null){
          $collection | where {$_.DescriptionId -eq "VirtualMachine.createSnapshot" -and $_.State -eq "success" -and $_.EntityName -eq $guestName} | %{
             $row = New-Object PsObject
             $row | Add-Member -MemberType NoteProperty -Name User -Value $_.Reason.UserName
             $vm = Get-View $_.Entity
             $snapshot = Get-SnapshotTree $vm.Snapshot.RootSnapshotList $_.Result
             $key = $_.EntityName + "&" + ($snapshot.CreateTime.ToString())
             $report[$key] = $row
          }
          $collection = $collectionImpl.ReadNextTasks($tasknumber)
       }
       $collectionImpl.DestroyCollector()
     
       # Get the guest's snapshots and add the user
       $snapshotsExtra = $snap | % {
          $key = $_.vm.Name + "&" + ($_.Created.ToString())
          if($report.ContainsKey($key)){
             $_ | Add-Member -MemberType NoteProperty -Name Creator -Value $report[$key].User
          }
          $_
       }
       $snapshotsExtra
    }
     
    Function SnapMail ($Mailto, $snapshot)
    {
       $msg = new-object Net.Mail.MailMessage
       $smtp = new-object Net.Mail.SmtpClient($smtpServer)
       $msg.From = $MailFrom
       $msg.To.Add($Mailto)
     
       $msg.Subject = "Snapshot Reminder"
     
    $MailText = @"
    This is a reminder that you have a snapshot active on $($snapshot.VM) which was taken on $($snapshot.Created).
     
    Name: $($snapshot.Name)
     
    Description: $($snapshot.Description)
    "@
     
       $msg.Body = $MailText
       $smtp.Send($msg)
    }
     
    Connect-VIServer $VISRV
     
    foreach ($snap in (Get-VM | Get-Snapshot | Where {$_.Created -lt ((Get-Date).AddDays(-14))})){
       $SnapshotInfo = Get-SnapshotExtra $snap
       $mailto = ((Find-User $SnapshotInfo.Creator).Properties.mail)
       SnapMail $mailto $SnapshotInfo
    }
    AD User created since x date (used for auditors)

    Code:
    get-aduser -filter * -properties whencreated | where {$_.whencreated -ge [datetime]"1/5/2016"} | sort-object whencreated | select sAMAccountName,Name,WhenCreated,enabled | export-csv C:\Users\XXXXXXX\Documents\UsersSinceMay01.csv
    Domain OS versions:

    Code:
    #Functions
    function ImportADModule
    {
      Import-Module ActiveDirectory
      if (!($?))
      {
        #Only works for Windows Server OS with PS running as admin, download RSAT if using desktop OS
        Add-WindowsFeature RSAT-AD-PowerShell
        Import-Module ActiveDirectory
      }
    }
    
    function GetDN
    {
      param($domain)
      $names = $domain.Split(".")
      $bFirst = $true
      foreach ($name in $names)
      {
        if ($bFirst)
        {
          $dn += "DC=" + $name
          $bFirst = $false
        }
        else { $dn += ",DC=" + $name }
      }
      return $dn
    }
    
    function GetDNs
    {
      param($domains)
      $dns = @{}
      foreach ($domain in $domains)
      {
        $dns.Add($domain, (GetDN -domain $domain))
      }
      return $dns
    }
    
    function GetOSCountsPerDomain
    {
      param($dns, $enabled, $daysOld)
      $osCounts = @{}
      $cutOffDate = ((Get-Date).Adddays(-($daysOld))).ToFileTime()
      Write-Host "Getting Data" -NoNewline -ForegroundColor Yellow
    
      $filter = "(PwdLastSet -gt {0}) -and (Enabled -eq '{1}')" -f $cutOffDate, $enabled
      foreach ($domain in $dns.GetEnumerator())
      {
        $i = 0
        $domains = @{}
        Write-Host "." -NoNewline -ForegroundColor Yellow
        $computers = Get-ADComputer -Filter $filter -SearchBase $domain.Value -Server $domain.Key -Properties OperatingSystem, OperatingSystemVersion
        foreach ($computer in $computers)
        {
          if ($computer.OperatingSystem -eq $null) { $os = 'NULL'}
          else { $os = $computer.OperatingSystem }
          if ($computer.OperatingSystemVersion -eq $null) { $osver = 'NULL'}
          else { $osver = $computer.OperatingSystemVersion }
          try { $domains.Add(($os + " - " + $osver), 1) }
          catch { $domains.Set_Item(($os + " - " + $osver), ($domains.Get_Item($os + " - " + $osver))+1) }
        }
        $osCounts.Add($domain.Key, $domains)
      }
      Write-Host
      return $osCounts
    }
    
    function DisplayOutput
    {
      param($osCounts)
      Write-Host
      foreach ($osCount in $osCounts.GetEnumerator())
      {
        Write-Host $OSCount.Key -ForegroundColor Green
        $osCount.Value.GetEnumerator() | Sort-Object Value -Descending | Format-Table -AutoSize
      }
    }
    
    #Main
    
    #Import AD Module for PowerShell
    ImportADModule
    
    #Get list of domains from current forest
    $Domains = (Get-ADForest).domains
    
    #Get hash table of domains and distinguished names from current forest
    $DNs = GetDNs -domains $Domains
    
    #Get OS counts per domain (specify age here)
    $OSCounts = GetOSCountsPerDomain -dns $DNs -enabled $true -daysOld 30
    
    #Display Results
    DisplayOutput -osCounts $OSCounts
     
  9. Pigeon_Killer

    Caporegime

    Joined: Nov 21, 2005

    Posts: 29,036

    Going to use that password one as well thanks :)

    Cjwdev has a few tools that have replaced the majority of scripts I ran, highly recommend their AD Info tool.
     
  10. LizardKing

    Soldato

    Joined: Oct 18, 2002

    Posts: 7,278

    Location: The Land of Roundabouts

    Very handy, i noticed they had enabled scripting a few weeks back and was going to look into automating it, just saved me the hassle :)

    I was asked by a client to setup a poormans regular clone of a server, the built in scheduler annoyingly doesn't allow for deleting of target VM's so had to be scripted.
    Luckily i found this little gem so didnt need to write something myself :D

    If this is set up as a daily task on a server with PowerCli installed then it will create a clone of a VM on another host which will then get deleted and re-cloned when run again.
    Original
    http://luckyblogshere.blogspot.co.uk/2012/08/delete-vm-then-clone-vm-powershell.html

    I only moved most of the params to the top and specified a resource pool for the clone to be created in.
    Code:
    $date = Get-Date
    $vcServer = "Vcenter server"
    $fromVMname = "VMtoClone"
    $newVMName = "Clone_OfServer"
    $tgtEsxName = "Target_ESXI_Host"
    $tgtDatastoreName = "datastore001"
    $userName = "root"
    $passWord = "Password"
    $notes = ("Clone of: " + $fromVMname + " for backup. Created on: " + $date)
    $ResPool = "Backup"
    $emailto = "yaddayadd@me.com"
    $emailFrom = "Server@me.com"
    $smtpServer = smtpserver.domain.name
    # Connect to the vCenter Server
    Add-PSSnapin –Name VM*
    Connect-VIServer -Server $vcServer -User $username -Password $passWord
    
    
    
    
    #
    # Test to see if $newVMname already exists in vCenter Server and
    # set $vmExist to a value other than $null if it does
    $vmExist = Get-VM -Name $newVMname -ErrorAction SilentlyContinue
    
    
    
    # Delete the VM $newVMname if $vmExist returns a value other than $null
    if ($vmExist -ne $null)
    {
     Remove-VM -deletefromdisk -VM $newVMName -confirm:$false
    }
    #
    # Create a clone of $fromVMname to $newVMName, email if there is an error
    $cloneTask = New-VM -Name $newVMName -VM (Get-VM $fromVMname) -VMHost (Get-VMHost $tgtEsxName) -Datastore (Get-Datastore $tgtDatastoreName) -ResourcePool $ResPool -RunAsync
    Wait-Task -Task $cloneTask -ErrorAction SilentlyContinue
    Get-Task | where {$_.Id -eq $cloneTask.Id} | %{
         if($_.State -eq "Error"){
              $event = Get-VIEvent -Start $_.FinishTime | where {$_.DestName -eq $newVMName} | select -First 1
              $subject = "Clone of " + $newVMName + " failed"
              $body = $event.FullFormattedMessage
    
              $smtp = new-object Net.Mail.SmtpClient($smtpServer)
              $smtp.Send($emailFrom, $emailTo, $subject, $body)
         }
    }
    #
    # Set the notes field of the VM $notes
    Set-VM -VM $newVMName -Notes $notes -confirm:$false
    #
    #Disconnect from the vCenter Server
    Disconnect-VIServer -Server $vcServer -Confirm:$false
     
  11. teaboy5

    Soldato

    Joined: Jan 12, 2006

    Posts: 5,260

    Location: NI

    Would anyone know of a powershell script that I could run on a large number of shares/folders to check if that user has permissions on the folder?

    P.S Got sorted in the end
     
    Last edited: Jun 17, 2017
  12. gman1981

    Associate

    Joined: Jun 23, 2009

    Posts: 52

    Can you post how you did it? I'm interested.
     
  13. clocka

    Wise Guy

    Joined: Jan 28, 2007

    Posts: 1,750

    Location: Manchester

    office365, when a team/manager asks you for a list of who has permissions to a shared mailbox. The script lists Full Mailbox Access, SendOnBehalfOf and SendAs. If anyone figures out how to list the UPN for SendOnBehalfOf please let me know :)

    Code:
    $mailboxupn = Read-Host -Prompt 'Enter mailbox upn'
    
    write-host $mailboxupn "Mailbox Permissions" -ForegroundColor Yellow
    write-host " "
    
    #Full Mailbox Access
    write-host "Full Mailbox Access" -ForegroundColor Yellow  
    $tempdata1 = Get-MailboxPermission -Identity $mailboxupn | Where-Object {($_.IsInherited -eq $false) -and ($_.User -notlike "NT AUTHORITY\SELF")} | select User
    #$tempdata1 -replace "User", "" -replace "@{=", "" -replace "}", ""
    foreach ($tempitem1 in $tempdata1) {
        write-host $tempitem1.User
    }
    
    #SendAs
    write-host " "
    write-host "SendAs permissions" -ForegroundColor Yellow  
    #Get-RecipientPermission -Identity $mailboxupn | Where-Object {($_.accessrights -like 'SendAs') -and -not ($_.trustee -like 'NT AUTHORITY\SELF')} | select Trustee
    $tempdata2 = Get-RecipientPermission -Identity $mailboxupn | Where-Object {($_.trustee -notlike 'NT AUTHORITY\SELF')} | select Trustee
    foreach ($tempitem2 in $tempdata2) {
        write-host $tempitem2.Trustee
    }
    
    #SendOnBehalfOf
    write-host " "
    write-host "SendOnBehalfOf permissions" -ForegroundColor Yellow  
    $tempdata3 = Get-Mailbox -Identity $mailboxupn | select GrantSendOnBehalfTo
    foreach ($tempitem3 in $tempdata3) {
        write-host $tempitem3.GrantSendOnBehalfTo
    }
     
  14. Spammeh

    Hitman

    Joined: Aug 2, 2005

    Posts: 551

    Me too @teaboy5
     
  15. JonnyT

    Wise Guy

    Joined: Oct 18, 2002

    Posts: 1,889

    Location: Cambridge

  16. Battery!

    Hitman

    Joined: Feb 28, 2014

    Posts: 821

    Great thread idea, I will add some later if I get a chance.
     
  17. Little_Crow

    Hitman

    Joined: Oct 3, 2007

    Posts: 696

    Not a script, but the Quest ActiveRoles Management Shell deserves an honourable mention.

    The functions are extremely similar to the standard AD powershell module, but I've found them far more intuitive and powerful.
    When searching for powershell scripts I do occasionally find a script with the tell that every function is prefixed with a 'Q', Qaduser, Qadgroup, etc.

    They were available for free from Quest before they got purchased by Dell, so 1.5.1 is the last free version available.
    Not sure about linking to a download, so here's the SHA1 hash from my copy:
    739d646f626a064200eb14d8ce1b8eb8634ee1d4
     
  18. Little_Crow

    Hitman

    Joined: Oct 3, 2007

    Posts: 696

    In fact, here's a script using the QAD functions I frequently use that checks every domain controller for the true last login time - Rather than the 'within 7 days' you'll get when querying a single DC.

    Couldn't say what site I got this from, but the author is credited

    Code:
    ##==============================================================================
    ##==============================================================================
    ## SCRIPT.........: Get-AllUserLastLogon
    ## AUTHOR.........: Clint McGuire
    ## EMAIL..........:
    ## VERSION........: 1
    ## DATE...........: 2011_05_26
    ## COPYRIGHT......: 2011, Clint McGuire
    ## LICENSE........:
    ## REQUIREMENTS...: Powershell v2.0, Quest AD Cmdlets
    ## DESCRIPTION....: Gets all enabled users last logon times and exports to CSV file.
    ## NOTES..........:
    ## CUSTOMIZE......:
    ##==============================================================================
    ## REVISED BY.....:
    ## EMAIL..........:
    ## REVISION DATE..:
    ## REVISION NOTES.:
    ##
    ##==============================================================================
    ##==============================================================================
    
    ##==============================================================================
    ## START
    ##==============================================================================
    $DCs = Get-QADComputer -ComputerRole DomainController
    $LastLogon = @{}
    ForEach ($DC in $DCs) {
    $Users = Get-QADUser -Service $dc.dnshostname -SizeLimit 0
    ForEach ($User in $Users)
    {
    If ($User.LastLogonTimestamp -ne $null)
    {
    $Time = $User.LastLogonTimestamp | Get-Date -Format u
    }
    Else
    {
    $Time = $User.LastLogonTimestamp
    }
    $UserName = $User.SamAccountName
    If ($LastLogon.ContainsKey($UserName))
    {
    If ($LastLogon.Get_Item($UserName) -le $Time)
    {
    $LastLogon.Set_Item($UserName, $Time)
    }
    }
    Else
    {
    $LastLogon.Add($UserName, $Time)
    }
    }
    }
    $LastLogon.GetEnumerator() | Sort-Object Name |Export-csv e:\powershell\AllADUserLastLogon.csv
    ##==============================================================================
    ## End
    ##==============================================================================
     
  19. teaboy5

    Soldato

    Joined: Jan 12, 2006

    Posts: 5,260

    Location: NI


    Hey sorry only seen this. In the end I had to add a security group to every folder over 7 file servers! I used the icacls command to force the group to all the folders. Allows me to simply remove the members of the group after or add more if I need too.
     
  20. Little_Crow

    Hitman

    Joined: Oct 3, 2007

    Posts: 696

    For anything complicated with file and directory permissions I use SetACL.

    When we migrated all of our home directories and file shares we used it to apply all the permissions we needed. I tested icacls, but it was far harder to get the granularity of permissions and inheritance we wanted.

    I've just looked through the documentation as a refresher and it's pretty daunting. Bit worrying as I think another migration to 2012R2/2016 might be in my not too distant future.
     


Share This Page