Get-Rules

By Ace Fekay
Published 2/21/2018

Intro

This is another quick script I created to help my day to day tasks. I hope you find it helpful.

Like I said before, I’m far from being an expert, but I continue to read up on it, research, and ask lots of questions. The more you work at something, the more you get something out of it. Ever play pool?

Scope

This script will enumerate the Inbox rules for a mailbox. You will have four options:

  1. List of rules without a description using FT
  2. List of rules with a description using FT
  3. Rules listed individually using FL
  4. Rules sent to a CSV file named based on the user account entered

Get-Rule Script

Copy and paste the following into notepad, and save it as Get-UserList.ps1, and run it to load the function.

#################################\\\\\\\\\\\\\\\\////////////////#################################
# This script will:
# 1. Read a console entry for a user accounts, whether a sAMAccountName, alias, or email address
# 2. Provide a list of rules without descriptions
# 3. Provide a list of rules with descriptions
#
#    .SYNOPSIS
#    Lists a User’s Mailbox InboxRules
#
#    .DESCRIPTION
#    Enumerate Inbox rules with and without a description
#
#    .PARAMETER User
#    Specific user you want to search for.
#
#    .PARAMETER Description
#    You want the rules listed out individually with a description
#
#    .PARAMETER NoDescription
#    You want the rules listed out in table format without a description
#
#    .PARAMETER NoDescription
#    You want the rules listed out in table format without a description
#
#################################\\\\\\\\\\\\\\\\////////////////#################################
# Variables

$RecipientName = “I823135”
$RecipientDisplayName = (get-recipient $RecipientName).displayname
$RecipientNetBIOSName = (get-recipient $RecipientName).name
$RecipientPrimAlias = (get-recipient $RecipientName).PrimarySmtpAddress

# Script

Function Get-Rules {
[CmdletBinding()]
Param (
[Parameter(Position=0,Mandatory=$true)]
[string]$RecipientName,

[Parameter(Mandatory=$false)]
[switch]$Description,

[Parameter(Mandatory=$false)]
[switch]$NoDescription,

[Parameter(Mandatory=$false)]
[switch]$IndividualList,

[Parameter(Mandatory=$false)]
[switch]$CSVFile
)

$RecipientDisplayName = (get-recipient $RecipientName).displayname
$RecipientNetBIOSName = (get-recipient $RecipientName).name
$RecipientPrimAlias = (get-recipient $RecipientName).PrimarySmtpAddress

#If -Description was selected – Inboxrules to Console Screen:
If ($NoDescription) {
Write-Host “=================================================================================================” -ForegroundColor Cyan
Write-Host “You’ve selected to List the Inbox Rules to the Console Without a Description” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | ft @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype -Wrap -a
Write-Host “=================================================================================================” -ForegroundColor Cyan
}

#If -NoDescription was selected – Inboxrules to Console Screen :
If ($Description) {
Write-Host “You’ve selected to List the Inbox Rules to the Console With a Description” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | ft name,enabled,priority,ruleidentity,RedirectTo,movetofolder,inerror,errortype,description    -Wrap
#    Get-InboxRule -Mailbox $RecipientName -IncludeHidden | ft -AutoSize
#    (Get-InboxRule -Mailbox $RecipientName -IncludeHidden | ft -AutoSize).count
# FL –      Get-InboxRule -mailbox $RecipientName -IncludeHidden | fl @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
# Select –  Get-InboxRule -mailbox $RecipientName -IncludeHidden | select  @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
Write-Host “=================================================================================================” -ForegroundColor Cyan
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
Write-Host “=================================================================================================” -ForegroundColor Cyan
}
#################################\\\\\\\\\\\\\\\\////////////////#################################

#If -IndividualList is selected
If ($IndividualList) {
Write-Host “You’ve selected to list each InboxRule individually” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | fl @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
Write-Host “=================================================================================================” -ForegroundColor Cyan
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
Write-Host “=================================================================================================” -ForegroundColor Cyan
}
#################################\\\\\\\\\\\\\\\\////////////////#################################

 

If ($CSVFile) {
#####################################################################################
#Inboxrules to CSV file
Write-Host “=================================================================================================” -ForegroundColor Cyan
Write-Host “You’ve selected to send the Inbox Rules to a CSV file.” -ForegroundColor Magenta
Write-host
Write-Host “Rules list was sent to a CSV file located at ***C:\temp\InboxRules-for-$RecipientName.csv***” -ForegroundColor Yellow
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
#Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | select @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,description | export-csv “C:\temp\InboxRules-for-$RecipientName.csv”
Write-Host “=================================================================================================” -ForegroundColor Cyan
} }

 

How to run it

Create a list in notepad, save it as a txt file in c:\temp, or anywhere else and reference that in the script, then run:

get-Rules aceman –description –nodescription –individuallist –csv

Summary

I hope this helps!

Published 2/21/2018

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2012|R2, 2008|R2, Exchange 2013|2010EA|2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Mobility

As many know, I work with Active Directory, Exchange server, and Office 365 engineer/architect, and an MVP in Active Directory and Identity Management, and I’m an MCT as well. I try to strive to perform my job with the best of my ability and efficiency, even when presented with a challenge, and then help others with my findings in case a similar issue arises to help ease their jobs. Share the knowledge, is what I’ve always learned.

I’ve found there are many qualified and very informative websites that provide how-to blogs, and I’m glad they exists and give due credit to the pros that put them together. In some cases when I must research an issue, I just needed something or specific that I couldn’t find or had to piece together from more than one site, such as a simple one-liner or a simple multiline script to perform day to day stuff.

I hope you’ve found this blog post helpful, along with my future scripts blog posts, especially with AD, Exchange, and Office 365.

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.


PowerShell Script to Search Netlogon for a Specific List of Script files to Replace or Alter Drive Mappings

Updates/Edits:

10/12/2015: I’ve updated the script to allow multiple, simultaneous changes for a list of bat files, and no need to manually add “.bat” to the list of user account samAccount names.

Prologue

Yes, it’s me again, Ace Fekay.

You’ve already *probably* read my recent blog:

PowerShell Script to Search Netlogon logon scripts and Replace Drive Mappings – 9/10/2015
https://blogs.msmvps.com/acefekay/2015/09/10/script-to-search-netlogon-logon-scripts-and-replace-drive-mappings/

That blog is about searching all script files that end with *.bat, and make changes to the files.

This time we’re going to run something similar, but for a strict list of specific files (user logon scripts) for a list of users. This came about when a request came in to remove access to 140 users and remove their drive mappings, and another request to alter access for 120 users’ scripts.

To remove drive mapping is easy. The following shows our normal mapping method in each script:

:: Access has been provided by Ace Fekay on 10/3/2015 with approval in Ticket# 123456
net use t: /del
net use t: \\contoso.com\sharename

And for the ones we are removing access, we can keep the net use t: .del to delete the mappings when the user logs on, but we want to comment out the mapping, as such:

::Access Removed per Ace Fekay in Ticket# 123456 – net use x: \\contoso.com\SomeShareName$

And of course, this is based on reading a list of script.bat file names in a text file appropriately called, “SomeShareNameRemoveMappingsUserListBat.txt.”

Have fun!

Script:

– Updated script: 10/11/2015:

# *************************************************************************************
# If this is a migration, first run the robocopy script to copy all data
# Then run the netlogon report script to see how many bat files in netlogon
#    reference OldServerName
# Then run this script to replace any reference to OldServerName in the batch
#    files for each share.
# *************************************************************************************
# Modified by Ace Fekay 10/11/2015
#
# Changes:
#    Input file just needs to be samAccount names and no longer need .bat suffixed
#    Allows to change multiple scripts as long as they have a common name,
#    such as the server name
#    Accommodates if the multiple users have different mapped drive letters.
#
# *************************************************************************************

get-credential

# Used for testing – $Path = “\\contoso.com\NETLOGON\test-RemoveMapping2”

$Path = “\\contoso.com\NETLOGON”
$WhatAmIlookingFor = “contoso.com”

#This grabs the list of user UserAccounts from the input file.
$SourceListOfUserAccounts = “C:\PSScripts\Netlogon Search and Replace\UserFileList.txt”

#Example of UserFileList.txt:
# username1
# username2
# username3
# etc

cd $Path
$RemoveMappedDriveFromUserList = (get-content $SourceListOfUserAccounts)
$UserCount = 0
$MappingsRemoved = 0

Foreach ($User in $RemoveMappedDriveFromUserList) {

#This will annotate/suffix “.bat” to the end of each user name
$UserScript = $User+”.bat”
$UserCount++

$file = get-content $UserScript

    #only modify files that contain the string $WhatAmILookingFor
    if (Select-String -InputObject $file $WhatAmIlookingFor){

$MappingsRemoved++

    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName1″,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\contoso.com\ShareName1
    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName2\$”,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\Malvern\output$ \\contoso.com\ShareName2$
    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName3″,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\contoso.com\ShareName3

# *************************************************************************************
# Previous stuff I kept here for future reference but commented out:
#    $file = $file -replace “\\\\OldServerName\\ShareName1$”,”\\contos.com\ShareName1$”
#    $file = $file -replace “\\\\OldServerName\\ShareName2″,”\\contos.com\ShareName2”
#    $file = $file -replace “\\\\OldServerName\\ShareName3″,”\\contos.com\ShareName3”
#    $file = $file -replace “\\\\OldServerName\\ShareName4″,”\\contos.com\ShareName4”
#    $file = $file -replace “\\\\OldServerName\\ShareName5″,”\\contos.com\ShareName5”
#    $file = $file -replace “\\\\OldServerName\\ShareName6″,”\\contos.com\ShareName6”
#    $file = $file -replace “\\\\OldServerName\\ShareName7″,”\\contos.com\ShareName7”
#    $file = $file -replace “\\\\OldServerName\\ShareName8″,”\\contos.com\ShareName8”
#    $file = $file -replace “\\\\OldServerName\\ShareName9″,”\\contos.com\ShareName9”
# *************************************************************************************
   
#comment out net time statements if they exist
    $file = $file -replace “^net time”,”REM net time”
   
#write out the changes
    Set-Content -Value $file -Path $UserScript
    write-host $UserScript “was changed to” $file
    }
}

write-host “Total users:” $UserCount
write-host “Total Mappings removed:” $MappingsRemoved
# *************************************************************************************
# *************************************************************************************

– Old script prior to 10/10/2015:

# *************************************************************************************
# If this is for post-migration, first run the robocopy script to copy all data
# Then run the netlogon search report script to see how many script.bat files in netlogon reference SomehareName
# Then run this to replace any reference to SomeShareName to TheNewShareName or even just to disable the share or shares.
# Highly modified by Ace Fekay 10/3/2015
# *************************************************************************************

get-credential

$Path = “\\contoso.com\NETLOGON”

# This code snippet gets all the files in $Path that end in “.bat”.
cd $Path

$RemoveMappedDriveFromUserList = (get-content “C:\PSScripts\Netlogon Search and Replace\SomeShareNameRemoveMappingsUserListBat.txt”)
 
$UserCount = 0
$MappingsRemoved = 0

Foreach ($User in $RemoveMappedDriveFromUserList) {
$UserCount++
$file = $RemoveMappedDriveFromUser

# Only modify files that contain the string “SomeShareName”
    if (Select-String -InputObject $file “SomeShareName”){

$MappingsRemoved++

# Note that the following is doing a number of things, such as commenting out mappings that they are no longer permitted to use,
# providing comments, changing or updating sharenames, etc.
    $file = $RemoveMappedDriveFromUser
    $file = $file -replace “net use g\: \\\\contoso.com\\SomeShareName\$”,”::Access Removed per Ace Fekay in Ticket# 123456 – net use g: \\contoso.com\SomeShareName$”
    $file = $file -replace “net use X\: \\\\contoso.com\\SomeShareName\$”,”::Access Removed per Ace Fekay in Ticket# 123456 – net use x: \\contoso.com\SomeShareName$”
    $file = $file -replace “net use z\: \\\\contoso.com\\SomeOldShareName\$”,”net use z: \\contoso.com\SomeNewShareName$”
    $file = $file -replace “\\\\OldServerName\\ShareName1$”,”\\contoso.com\ShareName1$”
    $file = $file -replace “\\\\OldServerName\\ShareName2$”,”\\contoso.com\ShareName2$”
    $file = $file -replace “\\\\OldServerName\\ShareName3$”,”\\contoso.com\ShareName3$”
    $file = $file -replace “\\\\OldServerName\\ShareName4$”,”\\contoso.com\ShareName4$”
    $file = $file -replace “\\\\OldServerName\\ShareName5$”,”\\contoso.com\ShareName5$”

# Comment out net time statements
    $file = $file -replace “^net time”,”REM net time”
   
# Write out the changes
    Set-Content -Value $file -Path $_;
    }
}

write-host “Total users:” $UserCount
write-host “Total Mappings removed:” $MappingsRemoved
# *************************************************************************************

 

More to come…

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 10/3/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622[2][2][2] clip_image004622[2][2][2] clip_image006622[2][2][2] clip_image008622[2][2][2] clip_image010622[2][2][2] clip_image012622[2][2][2]

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

Migrate Files to a new File Server using RoboCopy, IP addresses, and Relative Paths using the Administrative Shares

Prologue

Ace Fekay here again.

You might say to yourself this is some really simple stuff. Sure, it might be, for the pro. As many of you know, I’m an avid Active Directory and Exchange server engineer/architect, and an MVP in Active Directory.

Therefore with AD, Exchange, and Office 365, you will find that scripting comes into play more and more with your daily tasks.  The main reason I’m posting simple scripts is that to get the job done, I just needed an arsenal of simple quickie scripts when called upon a simple task, such as this one, when tasked to quickly get a list of users in a group.

I hope this, and my future scripts, especially with Office 365, help you out.

Scope

This is one method to migrate data from one file server to another. I have one method that I will post later, that does it by the share names. This is to just get the two closer to having the same data before I run the final script.

DFS

Keep in mind, we use DFS. I will already have created a new target to the new file server for the current share, but keep the new targets disabled until ready to cut over.

However, when we cut over the target to the new server, we would like to shut off the shares on the source (old) server, to prevent anyone from using it. Of course, we’ve already communicated to the user base the migration schedule.

Therefore, since the shares will be deleted, we must rely on running this by using IP addresses and relative paths from the default administrative shares (c$, d$, etc).

Share and NTFS Permissions Backup

Yes, absolutely! You definitely want to back up your Share and NTFS permissions on this server just in case something happens! The following link is a great article to show you how to do it:

How to Back Up and Restore NTFS and Share Permissions
http://blogs.technet.com/b/askds/archive/2008/11/24/how-to-back-up-and-restore-ntfs-and-share-permissions.aspx

Easy? Nah…

Many may say this is simple stuff. Sure, for the seasoned scripter, which I’m not, The main reason I’m posting this, and I will be posting much more, including Office 365 scripts, is that I had to look it up. I’ve found various websites that provide how-tos, but when it comes to handling variables and piping, I’ve found there is no one place to get various examples and have found myself looking at multiple places to get this info, including my colleagues, who are extremely adept at scripting. With many place, I also see elaborate scripts that do more than what I need. They are fabulous blogs and websites, but sometimes I need the simple one-liners to perform day to day stuff.

Script:

/

# Uses relative paths
# Make sure you change directory to where your script is located on the computer you are running this before running
#
# =========================================================================================
#Function: Get the Total Size of Folder

function Get-Size
{
     param([string]$pth)
     “{0:n2}” -f ((gci -path $pth -recurse | measure-object -property length -sum).sum /1mb) + ” mb”
}
# =========================================================================================
#
cd “C:\PSScripts\OldServerName”

$SourceServerNetBIOSName =     “OldServerName”
$SourceServerIP =         “10.100.200.200”
$DestinationServerName =     “NewFileServer.contoso.com”

#**************************************************************************************
#Ignore this section
#Test files with only one share

#Note: This section was a test to see if I can get this script to work if there is only one share.
#I could not get it to work with one share. The reason is there must be two (2) or more shares for
#this to work, because I’m using an array. There is no such thing as a single array.

#$SourceServerPath =            @()
#$SourceServerShares =          @()
#$DestinationServerShareNames = @()

#$SourceServerPath =            Get-Content ‘.\OldServerName-Share-paths-test.txt’
#$SourceServerShares =          Get-Content ‘.\OldServerName-SourceSharesList-test.txt’
#$DestinationServerShareNames = Get-Content ‘.\OldServerName-DestinationSharesList-test.txt’

#Ignore this section
#**************************************************************************************

$SourceServerPath =            Get-Content ‘.\OldServerName-Share-paths.txt’
$SourceServerShares =          Get-Content ‘.\OldServerName-SourceSharesList.txt’
$DestinationServerShareNames = Get-Content ‘.\OldServerName-DestinationSharesList.txt’

$LogDestinationFolder = “.\Logs”
$LogfileName = $SourceServerNetBIOSName+”.txt”
$LogFileAndPath = $LogDestinationFolder+”\”+$LogfileName

# Checks for existence of a directory for log files if not, one gets created.
If (!(Test-Path -Path $LogDestinationFolder)){
    New-Item -ItemType directory -Path $LogDestinationFolder
}

write-host “Total Share count = ” $SourceServerShares.count

for ($i = 0; $i -lt $SourceServerShares.count; $i++){

    $srcpath = $SourceServerPath[$i] -replace ‘(.*):’,’$1$’
    #$srcpath = $SourceServerPath -replace ‘(.*):’,’$1$’
    $dstpath = $DestinationServerShareNames[$i]

    $FullSourcePath = “\\”+$SourceServerIP+”\”+$srcpath
    $FullDestPath = “\\”+$DestinationServerName+”\”+$dstpath

    write-host “”
   
    if ((Test-Path $FullSourcePath) -and (Test-Path $FullDestPath))
    {
        $log = $LogDestinationFolder + “\” + $SourceServerNetBIOSName + “-” + $SourceServerShares[$i] +”.txt”
        write-host “Current share’s log:” $Log
       
        robocopy $FullSourcePath $FullDestPath /E /R:1 /W:1 /TEE /log:$log | Out-String

    #This is trying different switches – Ignore
        #robocopy $FullSourcePath $FullDestPath /MIR /copy:DT /W:5 /R:1 /V /IT /FP /NFL /TS  /log:$log | Out-String

    #This was a local drive to drive attempt – Ignore
    #robocopy e:\users y: /copy:DATSO /E /R:1 /W5 /TEE /log:c:\robocopy.log

    write-host “Source path is: ” $srcpath
        write-host “Full Source Path is: ” $FullSourcePath
    write-host “Destination path is:” $dstpath
        write-host “Full Destination path is: ” $FullDestPath

        $SharesProcessedSoFar = $i + 1
        write-host “Shares processed so far =” $SharesProcessedSoFar ” out of a total share count of ” $SourceServerShares.count
        write-host “”
        Write-Host “”
    }

    else

    {
        write-host “Problem with: ”           $srcpath         “Destination sharename is:”     $dstpath
        write-host “Referencing full Source Path:” $FullSourcePath  “Destination Path:”         $FullDestPath
        $SharesProcessedSoFar = $i + 1
        write-host “Shares processed so far =” $SharesProcessedSoFar ” out of a total share count of ” $SourceServerShares.count
    }
}
write-host “Total Shares processed = ” $SourceServerShares.count

More to come…

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 10/3/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622[2][2] clip_image004622[2][2] clip_image006622[2][2] clip_image008622[2][2] clip_image010622[2][2] clip_image012622[2][2]

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.