Powershell – Invoke-Command Remote UAC Workaround

Apr 19, 2012 • Jonathan -

I recently had to install a software agent on several remote servers with that had UAC (User Account Control) enabled. The issue was with the way Invoke-Command runs the commands, it uses the credentials of the person/account running the script to authenticate with the server then tries to use another account to run the command the permissions or lowers the privileges of the user so that certain commands cannot be run. I was able to get the software to install using the SYSTEM account by using a work around with the task scheduler. The following snippet creates a scheduled task to run as SYSTEM on the remote server, starts the task, and then deletes the task. In my case all servers follow a common naming convention, however it wouldn’t be difficult to adapt this snippet to other environments.

$siteCodes = @('PDX','NYC','LAX')

ForEach ($x in $siteCodes) {
# create PSSession on remote server
$Session = New-PSSession -ComputerName "$x-fs.constoso.com"

# run command on remote server
$Job = Invoke-Command -ComputerName "$x-fs.contoso.com" -ErrorAction SilentlyContinue -ArgumentList $x -ScriptBlock {
param($site)

# get bogus time
$currTime = Get-Date
$currTime.AddMinutes(90)
$currTime = Get-Date $currTime -Format %H:m

# create scheduled task
schtasks /create /tn "SoftInstall" /ru SYSTEM /tr "\\$site-fs.contoso.com\setup.exe /some /switches /go /here" /sc once /st $currTime

# run the task
schtasks /run /tn "SoftInstall"

# sleep for 10 sec
Start-Sleep -s 10

# delete the task
schtasks /delete /f /tn "SoftInstall"
}

# close the PSSession
Remove-PSSession -Session $Session
}
.



Exchange 2010 – Locating Disconnected Mailboxes

Mar 19, 2012 • Jonathan -

Here is a quick Powershell function to make finding disconnected mailboxes easier.

Save this as Get-DisconnectedMailbox.ps1:

function Get-DisconnectedMailbox {
    [CmdletBinding()]
    param(
        [Parameter(Position=0, Mandatory=$false)]
        [System.String]
        $Name = '*'
    )

    $mailboxes = Get-MailboxServer
    $mailboxes | %{
        $disconn = Get-Mailboxstatistics -Server $_.name | ?{ $_.DisconnectDate -ne $null }
        $disconn | ?{$_.displayname -like $Name} |
            Select DisplayName,
            @{n="StoreMailboxIdentity";e={$_.MailboxGuid}},
            Database
    }
}

Open the Powershell console, and dot source the function, assuming PS1 is stored in c:\scripts

cd c:\scripts
. .\Get-DisconnectedMailbox.ps1
Get-DisconnectedMailbox mailserver1.contoso.com
.



Exchange 2010 – Determine Mailbox Sizes With Powershell

Mar 15, 2012 • Jonathan -

Below is a quick snippet for retrieving mailboxes sizes for all mailboxes in a specific mailbox database:

Get-MailboxDatabase -Identity "EXAMPLE" | Get-MailboxStatistics | where {$_.ObjectClass –eq “Mailbox”} | Sort-Object TotalItemSize –Descending | ft @{label=”User”;expression={$_.DisplayName}},@{label=”Total Size (MB)”;expression={$_.TotalItemSize.Value.ToMB()}},@{label=”Items”;expression={$_.ItemCount}} -auto
.



Powershell – Get Network Adapter Connection Speed

Mar 7, 2012 • Jonathan -

One-Liner to get network adapter speed in Powershell.

Get-WmiObject -ComputerName computer.contoso.com -Class Win32_NetworkAdapter | Where-Object { $_.Speed -ne $null -and $_.MACAddress -ne $null } | Format-Table -Property NetConnectionID,@{Label='Speed(MB)'; Expression = {$_.Speed/1MB}}
.



Powershell – Get Time On Remote Computer

Mar 6, 2012 • Jonathan -

Short but useful snippet to get the time on a remote computer using Powershell & WMI.

$rt = Get-WmiObject -Class Win32_OperatingSystem -ComputerName computer.consoto.com
$rt.ConvertToDateTime($rt.LocalDateTime)
.



Exchange 2010 – Move All Mailboxes From OU To Specific Database

Feb 24, 2012 • Jonathan -

I needed to move all mailboxes for accounts in a specific OU to a specific Mailbox Database. Below are the powershell commands I used to accomplish this.

To create the necessary move requests:

$ou = "constoso.com/account purgatory"
Get-Mailbox -OrganizationalUnit $ou | New-MoveRequest -TargetDatabase "Purgatory"

To clean up the move requests when complete:

Get-MoveRequest | Where-Object { $_.Identity -like "$ou*" -and $_.Status -eq "Completed" } | Remove-MoveRequest -Confirm:$false
.



Scripting – Delete Files and Folders Older Than X Days

Feb 23, 2012 • Jonathan -

Removing files / folders older than X days. This post contains a batch file, and a Powershell script that will do this.

Batch File:

@echo off
:: set folder path
set dump_path=c:\shares\dump

:: set min age of files and folders to delete
set max_days=7

:: remove files from %dump_path%
forfiles -p %dump_path% -m *.* -d -%max_days% -c "cmd  /c del /q @path"

:: remove sub directories from %dump_path%
forfiles -p %dump_path% -d -%max_days% -c "cmd /c IF @isdir == TRUE rd /S /Q @path"

Powershell:

# set folder path
$dump_path = "C:\shares\dump"

# set min age of files
$max_days = "-7"
 
# get the current date
$curr_date = Get-Date

# determine how far back we go based on current date
$del_date = $curr_date.AddDays($max_days)

# delete the files
Get-ChildItem $dump_path -Recurse | Where-Object { $_.LastWriteTime -lt $del_date } | Remove-Item
.



Exchange 2007 – EventID 9554 – Unable to update Mailbox SD in the DS

Feb 20, 2012 • Jonathan -

How to fix EventID 9554 in Exchange 2007. One of the following recurring events may appear in the Application Log of the Event Viewer every 30 minutes:

Unable to update Mailbox SD in the DS. Mailbox Guid: 844fec0b-405a-4e74-9b7d-3fea8e1373ae. Error Code 0x80070005
Unable to update Mailbox SD in the DS. Mailbox Guid: 844fec0b-405a-4e74-9b7d-3fea8e1373ae. Error Code 0x80070005 

First you need to determine what mailbox is having the issues. To do this we use the Exchange Management Shell:

Get-MailboxStatistics | Where-Object { $_.MailboxGuid -eq '844fec0b-405a-4e74-9b7d-3fea8e1373ae' } | ft DisplayName, MailboxGuid

Next we fix the permissions on the active directory object:

  1. Start the Active Directory Users and Computers snap-in.
  2. Right-click the user whose permissions you want to change, and then click Properties.
  3. Click the Security tab, click to select the Allow inheritable permissions from parent to propagate to this object check box, and then click OK.
.



Exchange 2010 – DAG Maintenance With Two Member DAGs

Jan 30, 2012 • Jonathan -

I ran into an issue when attempting to install Exchange 2010 SP2 on a two member dag. It turns out you can’t use the StartDAGServerMaintenance.ps1 and StopDAGServerMaintenance.ps1 scripts on a two node DAG because the 2nd part of StartDAGServerMaintenance fails to complete its tasks and cannot put the node into maintenance mode (although it does move the databases). Below is the procedure I used to manually put the DAG member into maintenance mode so I could install Exchange 2010 SP2. In the example MB-DAG2 is the member I wanted to put into maintenance mode, MB-DAG1 is the other node, and DAG.DOMAIN.COM is the DAG fqdn.

Verify that at least one other non-lagged copy of the replicated database(s) is healthy.

Get-MailboxDatabaseCopyStatus *

Move the databases to another node:

Move-ActiveMailboxDatabase -Server DAG-MB1 -Confirm:$FALSE

Move the cluster core resources to another node:

cluster dag.domain.com group "Cluster Group" /moveto:DAG-MB1

Pause the cluster node:

cluster dag.domain.com node DAG-MB1 /pause

Set the DatabaseCopyAutoActivationPolicy of the node to BLOCKED.

Set-MailboxServer -Identity DAG-MB1 -DatabaseCopyAutoActivationPolicy:BLOCKED

Suspend all individual database copies for activation.

Get-MailboxDatabaseCopyStatus *\DAG-MB1 | Suspend-MailboxDatabaseCopy -ActivationOnly:$TRUE

This is where you perform server maintenance (install Exchange 2010 SP2) on that the MB-DAG1 node. When the service pack install finished, I took the node out of maintenance:

Resume the node:

cluster dag.domain.com node DAG-MB1 /resume

Move the cluster resources back to the other node:

cluster dag.domain.com group "Cluster Group" /moveto:DAG-MB2

Resume the DB replication:

Get-MailboxDatabaseCopyStatus *\DAG-MB2 | Resume-MailboxDatabaseCopy

Done. Now repeat these steps for the other DAG member.

.



Exchange 2010 – Import PST Into Mailbox with CAS Array

Dec 27, 2011 • Jonathan -

Unfortunately, using the New-MailboxImportRequest cmdlet with a CAS array doesn’t work. To workaround this we will create a Temp database, set a specific CAS server as the RpcClientAccessServer for that mailbox database, move the target mailbox to it, import the PST, and then move the mailbox back to the original database. These instructions assume you have both the Active Directory and Exchange 2010 management powershell roles/modules enabled.

When you try to use New-MailboxImportRequest with a CAS array you will receive the following error:

Couldn’t connect to target mailbox.
First we will configure the prerequisites, then we can get to work. In order for this to work, you need the PSTs on a file share, make sure you grant “Exchange Trusted Subsystem” full access to this share, otherwise you will run into errors.

 

Create an active directory group to grant import/export access to:
New-ADGroup -Name "ImpEx_Admins" -SamAccountName ImpExAdmins -GroupCategory Security -GroupScope Universal -DisplayName "ImpEx Admins" -Path "CN=Users,DC=Contoso,DC=Com" -Description "Members of this group are mailbox import export administrators"

Grant the created group the necessary permissions to import/export mailboxes as PSTs:

New-ManagementRoleAssignment -Name "Import Export Mailbox Admins" -SecurityGroup "ImpEx_Admins" -Role "Mailbox Import Export"

Now add yourself to that group and we can continue.
Create temporary mailbox database to move mailbox to:

New-MailboxDatabase -Name "SomeTmpDB" -EdbFilePath D:\SomePath\MailboxDatabase01.edb -LogFolderPath D:\SomePath\LogFolder

Set the RCPClientAccessServer value on the temp database to a specific CAS server:

Get-MailboxDatabase TempDB | Set-MailboxDatabase -RpcClientAccessServer cas1.domain.com

Move mailbox to MDB that has specific CAS array set as RCPClientAccessServer:

New-MoveRequest -Identity '[email protected]' -TargetDatabase SomeTmpDB

Clear the mailbox move request for the mailbox

Remove-MoveRequest -Identity '[email protected]'

Import the PST into the mailbox in a folder name “Recovery”:

New-MailboxImportRequest -Mailbox someUser -FilePath \\someserver\c$\pst\anotherUser.pst -TargetRootFolder Recovery

Remove the Mailbox Import Request

Remove-MailboxImportRequest -Identity someUser

Move the mailbox back to the original mailbox database:

New-MoveRequest -Identity '[email protected]' -TargetDatabase OriginalDB

Once the move is complete, remove the move request:

Remove-MoveRequest -Identity '[email protected]'
.



subscribe via RSS