locked
Why doesn't my logon script run? RRS feed

  • Question

  • Hi,

    I'm trying to run a PowerShell script at logon, but nothing seem to happen:  I've tried gpupdate /force on the client and gpresult show that it has run.  Is there something I my script that would stop it running (it works locally)?

    Param(
    	[string]$SMTPServer = "smtp.domain.com",
    	[string]$From = "FolderRedirections@domain.com",
    	[string]$To = (Get-ADUser -Identity $env:username -Properties EmailAddress | Select EmailAddress),
    	[string]$Subject = "Profile Size"
    )
    # CSS for email
    $Style = "<Style>BODY{font-size:12px;font-family:verdana,sans-serif;color:navy;font-weight:normal;}" + `
    			"TABLE{border-width:1px;cellpadding=10;border-style:solid;border-color:navy;border-collapse:collapse;}" + `
    			"TH{font-size:12px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}" + `
    			"TD{font-size:12px;border-width:1px;padding:10px;border-style:solid;border-color:navy;}</Style>"
    
    # Function to Send the Email
    Function SendEmailStatus($From, $To, $Subject, $SMTPServer, $BodyAsHtml, $Body) {
    	$SMTPMessage = New-Object System.Net.Mail.MailMessage $From, $To, $Subject, $Body
    	$SMTPMessage.IsBodyHTML = $BodyAsHtml
    	$SMTPClient = New-Object System.Net.Mail.SMTPClient $SMTPServer
    	$SMTPClient.Send($SMTPMessage)
    	If($? -eq $False){Write-Warning "$($Error[0].Exception.Message) | $($Error[0].Exception.GetBaseException().Message)"}
    	$SMTPMessage.Dispose()
    	Remove-Variable SMTPClient
    	Remove-Variable SMTPMessage
    }
    
    
    Function Convert-BytesToSize {
        [CmdletBinding()]
        Param (
            [parameter(Mandatory=$False,Position=0)][int64]$Size
    
        )
    
        #Decide what is the type of size
        Switch ($Size) {
            {$Size -gt 1PB} {
                $NewSize = “$([math]::Round(($Size / 1PB),2))PB”
                Break
            }
            {$Size -gt 1TB} {
                $NewSize = “$([math]::Round(($Size / 1TB),2))TB”
                Break
            }
            {$Size -gt 1GB} {
                $NewSize = “$([math]::Round(($Size / 1GB),2))GB”
                Break
            }
            {$Size -gt 1MB} {
                $NewSize = “$([math]::Round(($Size / 1MB),2))MB”
                Break
            }
            {$Size -gt 1KB} {
                $NewSize = “$([math]::Round(($Size / 1KB),2))KB”
                Break
            }
            Default {
                $NewSize = “$([math]::Round($Size,2))Bytes”
                Break
            }
        }
     Return $NewSize
    }
    
    
    Clear-Host
    # Get Data
    $AppData = gci \\Server\RedirectedFolders\$env:username\AppData -Recurse | Measure-Object -Property length -Sum
    $Desktop = gci \\Server\RedirectedFolders\$env:username\Desktop -Recurse | Measure-Object -Property length -Sum 
    $Documents = gci \\Server\RedirectedFolders\$env:username\Documents -Recurse | Measure-Object -Property length -Sum
    $Downloads = gci \\Server\RedirectedFolders\$env:username\Downloads -Recurse | Measure-Object -Property length -Sum
    $Total = $Desktop.Sum +$Documents.Sum +$Downloads.Sum
    
    #Convert Data to meaningful values
    $AppData = Convert-BytesToSize -Size $AppData.Sum
    $Desktop = Convert-BytesToSize -Size $Desktop.Sum
    $Documents = Convert-BytesToSize -Size $Documents.Sum
    $Downloads = Convert-BytesToSize -Size $Downloads.Sum
    $GTotal = Convert-BytesToSize -Size $Total
    
    #Body of Email
    $Msg = "<style><Body><p>blah blah.</p>"
    $Msg += "<p>Your profile currently stands at:</p>"
    $Msg += "<table>"
    $Msg += "<tr><th>Folder</th><th>Size</th>"
    $Msg += "<tr><td>Desktop</td><td>$Desktop</td></tr>" 
    $Msg += "<tr><td>Documents</td><td>$Documents</td></tr>"
    $Msg += "<tr><td>Downloads</td><td>$Downloads</td></tr>"
    $Msg += "<tr><td>Total</td><td>$GTotal</td></tr>"
    $Msg += "</table>"
    $Msg += "<p>Kind regards<br>"
    $Msg += "The IT Team</p></Body></style>"
    
    $Body = ConvertTo-HTML -head $Style -body $Msg
    
    #Send Email
    #If ($GTotal -ge 2GB) {
        SendEmailStatus -From $From -To $To -Subject $Subject -SmtpServer $SmtpServer -BodyAsHtml $True -Body $Body
    #}

    Thanks
    Tony

    Tuesday, June 21, 2016 1:55 PM

Answers

  • Hi Tony,

    if the computer that should run it via GP doesn't have the AD module, it will fail.
    if the script takes too long to run, group policy may kill it.

    That's pretty much the only prerequisite based on script content. You may have other trouble on the task setup (such as parameterization, user permissions or ExecutionPolicy).

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, June 21, 2016 2:28 PM

All replies

  • If the script works locally, then you don't have a scripting question.

    Ask in the group policy forum.


    -- Bill Stewart [Bill_Stewart]

    Tuesday, June 21, 2016 2:09 PM
  • Hi Tony,

    if the computer that should run it via GP doesn't have the AD module, it will fail.
    if the script takes too long to run, group policy may kill it.

    That's pretty much the only prerequisite based on script content. You may have other trouble on the task setup (such as parameterization, user permissions or ExecutionPolicy).

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, June 21, 2016 2:28 PM
  • You are kind of doing this the hard way.  Why would you want to do this on every logon.  It will kill logon speed and may create conflict.

    You can just use remote access to get the profile sizes. WMI will get profile location and you can get the sizes using that.  Tis can all be done remotely.

    Logon scripts are run async by default.  THIs makes them unreliable in many scenarios.

    I also see no error management so an error can abort your output and you would never know it.

    Start, as Bill has suggested, with the GP forum.  Ad tracing and error management to help troubleshoot.


    \_(ツ)_/

    Tuesday, June 21, 2016 2:31 PM
  • Thanks Fred.
    Tuesday, June 21, 2016 2:34 PM
  • I would agree. Trying to do all of this in a logon script seems like a bad idea. It would probably be better to tell what you're trying to do, rather than how you think it needs to be done.

    -- Bill Stewart [Bill_Stewart]

    Tuesday, June 21, 2016 2:56 PM
  • Hi Bill,

    What I am trying to do is:

    Get the size of Desktop, My Documents and Downloads of users Roaming Profiles and then email them the results.

    Tony

    Tuesday, June 21, 2016 3:33 PM
  • Why?

    -- Bill Stewart [Bill_Stewart]

    Tuesday, June 21, 2016 3:53 PM
  • I place all of these folders on a network drive.  This is done via Group Policy.  We can then use quotas and the auditing capability of file filters to notify users of usage and limits just like in Exchange.  There is no need to write scripts for this in modern Windows.


    \_(ツ)_/

    Tuesday, June 21, 2016 4:56 PM
  • Irrelevant - but...we are moving to W10 and the users have large profiles (some are 20GB+ - will be applying Quotas after the move).  We want them to housekeep (move to Personal Drive U:) to that:

    1. Make 1st logon to new PC quicker
    2. Logon times are reduced when moving between PC's
    3. Educate them to use the U: drive.

    I could write a script to do the move, which would satisfy 1 & 2 but not 3.

    Most of the issues are historical and ingrained, and we could just write blanket emails (but who reads emails from IT?).

    Wednesday, June 22, 2016 7:35 AM
  • You should be using folder redirection to remedy this.  You can redirect all but mydocuments and mypictures first then redirect those later as they will be the largest.

    We cannot solve a problem caused by unexpected use of logon scripts.  As noted above, long running scripts will be terminated by the GP script governor.  You cannot really fix this without causing other issues.

    I recommend using a scheduled task that runs after the user logs in and collects the info in the background.  Update the script to account for the newer version of PowerShell and post the file to the users desktop as well as sending an email.

    Don't be fancy while testing.  Check GP forum for instructions on deploying a scheduled task via a GPO.

    You will have to design and troubleshoot this. We cannot provide that kind of extended support. We can only answer scripting question.  If this is critical I recommend contacting a consultant who is experienced in migrations.


    \_(ツ)_/

    Wednesday, June 22, 2016 11:53 AM
  • Am using Folder Redirection ($AppData = gci \\Server\RedirectedFolders\$env:username).  Already answered - I was trying to run the AD Module on the client...which doesn't have it.  Have resolved using a different method.

    Thanks for the insights

    Wednesday, June 22, 2016 12:32 PM
  • Just scan user folders on redirected share and email them the results.  This does not need to be done at login. If redirected shares are set up correctly then the users samaccountname is the folder name so use that to sent the email.

    We have been doing this for years. With WS2008 file server we can use file filters on a set of folders and have the sizes reported automatically so it is no longer necessary to run these scripts.

    https://technet.microsoft.com/en-us/library/cc732074%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396

    Of course you have to learn a new technology and how to customize it but it is the way to go for the future.

    In any case running the script as a logon script will be an issue when running it from an admin station across all users can be much faster and less disruptive

    You can also use one of the short ADSI scripts in the gallery to get the users email address although running this from a management workstation with RSAT will give you access to Get-AdUser.

    Your method of selecting the users email Address might not work even if the module is available.  You are selecting an object and not the string.

    THis gets the current users mail address.

    ([adsisearcher]"samaccountname=$($env:username)").FindOne().Properties['mail']


    \_(ツ)_/


    • Edited by jrv Wednesday, June 22, 2016 12:47 PM
    Wednesday, June 22, 2016 12:43 PM
  • Thanks - corporate policy dictates that only the users have access to their redirected folders - therefore the script needs to run in the user context...not something I  as Admin (nor anyone else) can do.
    Wednesday, June 22, 2016 12:46 PM
  • Good luck with backups in that case.

    -- Bill Stewart [Bill_Stewart]

    Wednesday, June 22, 2016 2:51 PM
  • Actually, a properly set up system can make backups of Windows redirected folders that do not have :Admin: access. "Se_BackupPrivilege" gives an account that but it can only be used that way by properly registered backup processes running under the SYSTEM account. Admins can get access by just taking access.

    Tie issue here is a problem because many things requested will be a problem in a logon script.  Using the task scheduler executing in the user logon session can safely bypass most of these issues. It will also not be terminated by the GPO system because it runs for a long time.


    \_(ツ)_/

    Wednesday, June 22, 2016 2:57 PM
  • True, I kind of forgot about backup privilege...

    -- Bill Stewart [Bill_Stewart]

    Wednesday, June 22, 2016 3:04 PM
  • Here is a very much faster way of getting folder size as Windows pre-calculates this dynamically.

    PS > $fso=New-Object -ComObject Scripting.FileSystemObject
    PS > $f=$fso.GetFolder('\\SBS01\UserShares\jsmith\Downloads')
    PS > $f.Size
    694480739


    \_(ツ)_/


    • Edited by jrv Wednesday, June 22, 2016 3:05 PM
    Wednesday, June 22, 2016 3:05 PM
  • We can also do this for all special folders.

    $f=$fso.GetFolder([environment]::GetFolderPath('MyDocuments'))


    \_(ツ)_/

    Wednesday, June 22, 2016 3:12 PM
  • True, I kind of forgot about backup privilege...

    -- Bill Stewart [Bill_Stewart]

    I always forget about that.  I am surprised I remembered.


    \_(ツ)_/

    Wednesday, June 22, 2016 3:24 PM