Link to home
Start Free TrialLog in
Avatar of naifyboy123
naifyboy123Flag for Afghanistan

asked on

Powershell append output to Text file

Hi - i have the attached PS1 script which I use to enable or disbale ActiveSync in Exchange based on group membership.

Whilst the results are shown on screen I would like to add both the $mailbox is enabled and $mailbox is disabled to a text file.

This script will run every few hours and therefore rather than create a new text file each time it runs, I would like it to 'append' to the text, ideally showing date and time each line was added.

Please can one of you Powershell gurus help me :)

Thanks in advance
ActiveSyncManagement.txt
SOLUTION
Avatar of Navdeep
Navdeep
Flag of Singapore image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just check if there is property called identity for the $mailbox, else you can use can use some other property that reflects the user name

Regards,
ExchangeADTech [v-2nas]
Avatar of naifyboy123

ASKER

Thanks v-2nas - almost there - it works fine by appending to the same log file but as mentioned, is there a way to get a time/date stamp next to each line. Something like:

Current ouput
domain.local/Users/Terry Smith,True
domain.local/Users/Arthur Clarke,False

Required Output
21.09.2012_13.17.32 domain.local/Users/Terry Smith,True
21.09.2012_13.17.32 domain.local/Users/Arthur Clarke,False

Where time date format is: D/M/Y H/M/S

???
$DateFormat = Get-Date -format "dd.MM.yy_hh.mm.ss"
"$DateFormat $UserInfo" >> "TextFileAppending.txt"

HTH,

DH
Thanks DH - not sure how to encorporate that into the script. Are you able to show me based on the script provded?
Not a problem:

$mailboxes = Get-CASMailbox -resultSize unlimited
$asusers = Get-DistributionGroupMember -Identity 'ActiveSync Enabled'

$asguids = @()
foreach ($user in $asusers) {
    $asguids += $user.GUID
}

foreach ($mailbox in $mailboxes) {
    if ($asguids -contains $mailbox.GUID ) {
                $DateFormat = Get-Date -format "dd.MM.yy_hh.mm.ss"
        if ($mailbox.ActiveSyncEnabled -ne $true) {
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $true
               "$DateFormat;$($Mailbox.identity);True" >> "RunningLog.txt"
            "$mailbox is enabled"
        }
    }
    else {
        if ($mailbox.ActiveSyncEnabled -ne $false) {
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $false
               "$DateFormat;$($Mailbox.identity);False" >> "RunningLog.txt"
            "$mailbox is disabled"
        }
    }
}

Open in new window


v-2nas is technically correct in all of his code he provided, but I just provided maybe an easier way for you, with less code to worry about.

I put the $DateFormat in such a way that it will be accurate up to the second it gets written to the log, however, you could put that same line up top above the foreach statement to give you a less accurate statement, however the script would be doing less things.  You're essentially adding an additional calculation per mailbox, slowing down the overall script.

RunningLog.txt is created in the same directory from where you run your scripts.  Hopefully you run them out of the C:\scripts folder to make it easier.

I added the semicolons to the output so you can easily import into excel and separate by semicolon.

HTH,

DH
Hi guys - it works fine other than the "mailbox is disabled" and "mailbox is disabled" text is not written to the file.
Instead I get the following:

21.09.12_03.27.45 domain.local/Users/Athur.Clarke;False

One other little thing that is bugging me. Can I get this set to 24 hour clock. This ran at 3.27pm and the time shows as 03.27

Thanks
Naifyboy123,

I'd love to get right into teaching you a little about how this script works.  It seems you're not quite sure the flow and function of what's going on, which makes it very hard for you to modify this script in the future.  I'd love to "help", but it wouldn't be any good to do this for you, and have you walk away with zero knowledge gained.

The core of the entire script is the actual determination of the mailbox being enabled for activesync or not, which forks our path into two possible outcomes:

    if ($asguids -contains $mailbox.GUID ) {
                $DateFormat = Get-Date -format "dd.MM.yy_hh.mm.ss"
        if ($mailbox.ActiveSyncEnabled -eq $false) {
               #If we are here, it means the Active Sync is not enabled, so do this whole section here up until the } bracket
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $true
               #Below is the single output to the text file
               #The >> means "append" and the text file is specified afterwards
               #The first part of the quoted statement is the dateformat variable holding your date
               #The second part is your identity to your mailbox
               #The last part is the word True to let you know it was enabled
               "$DateFormat;$($Mailbox.identity);True" >> "RunningLog.txt"
               #The below statement is printed to the window, not the log
            "$mailbox is enabled"
               #If you want to add more to the log, simply add it to the statement that writes to the log
        }
    else 
   {
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $false
             "$DateFormat;$($Mailbox.identity);False" >> "RunningLog.txt"
            "$mailbox is disabled"
    }

Open in new window


Just to let you know, I did change the structure a bit since it was a little lengthy.  Here's the new simplified code from before (without comments)

$mailboxes = Get-CASMailbox -resultSize unlimited
$asusers = Get-DistributionGroupMember -Identity 'ActiveSync Enabled'

$asguids = @()
foreach ($user in $asusers) {
    $asguids += $user.GUID
}

foreach ($mailbox in $mailboxes) {
    if ($asguids -contains $mailbox.GUID ) {
        $DateFormat = Get-Date -format "dd.MM.yy_HH.mm.ss"
        if ($mailbox.ActiveSyncEnabled -eq $False) {
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $true
            "$DateFormat;$($Mailbox.identity);True" >> "RunningLog.txt"
            "$mailbox has been enabled"
        }
        else 
        {
            $mailbox | Set-CASMailbox -ActiveSyncEnabled $false
            "$DateFormat;$($Mailbox.identity);False" >> "RunningLog.txt"
            "$mailbox has been disabled"
        }#end if mailbox is activesync enabled/disabled
    }#end if asguids contains mailbox guid
}#end foreach mailbox

Open in new window


I also fixed it so your hh is now HH, resulting in 24-hour format.

Please take some time to read over the comments and truly understand what it's doing.  If you need some help, we are here to assist.  If you would like to learn more, there are great articles out there on EE to help you, including one that I wrote:
https://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/A_4327-PowerShell-Where-do-I-start.html

I hope you take the time to learn this wonderful language that really enhances your organization and saves tons of time.

Dale Harris
All well settled.....

Regards,
ExchangeADTec [v-2nas]
Upon further inspection, your script is actually set to enable activesync for mailboxes without activesync enabled, and disable the ones that have it enabled.

This essentially creates havoc within your environment every single time you run the script.

I wonder if there needs to be a modification to only do one of the if statement blocks?

DH
The original script (uploaded by me) set active sync enabled for all mailboxes (users) which are members of the Distribution Group called 'ActiveSync Enabled' and disabled it for any one who was not a member of this Dist Group.

I think maybe the original requirement of using the Dist group membership to govern who gets it enabled or disabled may have been lost along the way here.

I have just run your lastest script and it actually disbaled ActiveSync for all users that had it enabled.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Qlemo
... and you corrected the error that $DateFormat has been changed only in the first branch ...
I would like to slightly modify the script, as I hate repeated code:
$asguids = @()
foreach ($user in (Get-DistributionGroupMember -Identity 'ActiveSync Enabled')) {
    $asguids += $user.GUID
}

foreach ($mailbox in (Get-CASMailbox -resultSize unlimited)) {
    $DateFormat = Get-Date -format "dd.MM.yy_HH.mm.ss"
    $ASenabled = $mailbox.ActiveSyncEnabled
    if (($asguids -contains $mailbox.GUID) -ne $ASenabled) {
        Set-CASMailbox $mailbox -ActiveSyncEnabled !$ASenabled
        $txt =  "enabled"*!$ASenabled + "disabled"*$ASenabled
        "$DateFormat;$($Mailbox.identity);ActiveSync $txt" >> "RunningLog.txt"
        write-host "$mailbox has been $txt"
    }
}

Open in new window

Qlemo,

That is some advanced stuff.  Can you explain a little more how it works?  Even I'm a little confused on how the $txt variable is setup?

I think this is how it goes:

#This is where it assigns either a true or false value depending on the mailbox's current value.  Let's assume it's $False regardless of the fact if it's in the $asguids array or not for the first mailbox it finds
$ASenabled = $Mailbox.activesyncenabled
if current mailbox is in the $asguids array and it's not equal to $False, set the mailbox to the opposite of what it is.  Doesn't this set it to $True (!$False), which would be enabling a $true even though it's already been found that it's $True (-ne $ASenabled)?

I'm just confused and think I could learn from this simple yet complicated code.

I'm wondering if the -ne $ASenabled is supposed to be -eq $ASenabled?

DH
Lets call "current mailbox is in $asguids" condition A, and "is ActiveSync-enabled" condition B.  We then have following cases:
    A and not B => change (to enabled)
    A and     B => no change, is ok
not A and not B => no change, is ok
not A and     B => change (to disabled)

Open in new window

This is a boolean "not equivalent" condition, or  A != B (A -ne B).
If we have to make a change, B needs to be set to the opposite value => !B

Regarding $txt:  "A"*$true + "B"*$false  results in "A". That fact is handy for some conditional expressions, as they else would require a Pscx operator, or some complicated code. As a C++ programmer I prefer those conditional expressions over IF statements - if simple enough to understand immediately.
I added this to my knowledge base.  Seriously Qlemo, that's some great work.  I realize you've already been using it in another language, but it's great that you ported it over to use it in Powershell.
Hi all - thanks for the help you have given me here. I am assigned the points based on my original question and the fact that I ended up with a solution that answers the question and meets my requirement. Thanks again and yes, I need to read up and skill myself up more on Powershell