none
Elevate to "Run as Administrator" for a single command RRS feed

  • General discussion

  • So I like to try to automate various tasks using powershell.  I also like to send the status and what is being accomplished to the application event log as it progresses.  That way I can run a powershell command and grab all the events fir that script from the log.

    I do not want to have to pre-create the event source.  So in the beginning of the script I  am trying this code:

    # Initialize source for Application Event Log
    If ( -Not([System.Diagnostics.EventLog]::SourceExists('MyCurrentScript'))) 
        {
        New-EventLog -Source MyCurrentScript -LogName Application
        }

    However even if I am running powershell as a user that is in the local administrators group it does not work.  I have to start powershell in the "Run as an Administrator" mode to execute the following code:

    New-EventLog -Source MyCurrentScript -LogName Application

    But then if I have to do a bunch of Active Director privileged tasks they fail.

    So, how can I elevate to "Run as Administrator" for the one line???

    Thank you,


    Monday, June 8, 2015 8:25 PM

All replies

  • The usual way is to start your PowerShell session elevated to begin with.

    After it opens, run your script(s) that require elevation.


    -- Bill Stewart [Bill_Stewart]

    Monday, June 8, 2015 8:37 PM
    Moderator
  • Bill,

    How can you start as an administrator and have elevated privileges in Active Directory at the same time?

    Can you provide and example?

    Thank you,

    Rayzavs


    • Edited by Rayzavs1 Monday, June 8, 2015 8:41 PM typo
    Monday, June 8, 2015 8:41 PM
  • Right-click PowerShell icon, then click "Run as adminstrator" to run PowerShell elevated.

    Hold Shift key, right-click the PowerShell icon, then click "Run as different user" to run PowerShell as a different user.

    These are two different things.


    -- Bill Stewart [Bill_Stewart]

    Monday, June 8, 2015 9:25 PM
    Moderator
  • Both those are fine.  They are well known.  So my understanding is that on script may be launched from another.  Can one Run that Script in an elevated mode?  Can you pass a parameter to it?  If so how?  Then I think we could create a function to create the event log source. Then I can place that second script, "Event log source creator" in a repository and just call that if the event log source does not exist.  Then any server I move a script to run on would be able to create it and neither I nor my Team would need to remember to do do this. 

    I just find it hard to understand why even a domain admin account cannot create a new windows event log source.  I am not a good enough powershell script writer to do this.  It would seem that this would be a bit of a short fall of powershell if I cannot overcome this.  

    Here is  a whole example of on of the scripts.  The charge was to find stale computer objects.  Report on the changes and the counts of Live OS's in A.D.  The concern for this script was that the policy dictated that the computer account be first disabled then moved to a "Disabled" OU.  After it was there for 30 days it could then be deleted.  The policy was formed that way to mitigate worries from the desktop team about overwhelming tickets related to deleted accounts.  So I wrote the following script.  It may not be the best written code ever but it works for us.  I just need a little help with that one piece

    # Created by Rayzavs (6-5-2015) # This script is to perform Maintenance on Active Directory Computer Objects. # It Completes the Following Functions: # 1) Creates an event log Source for the script if it does not exist. then Logs all steps in the application log. # 2) Creates a report of the Counts of OS's in Active directory before it runs # 3) Finds Stale Computer accounts by 90 days and disables said stale accounts. # 4) Moves Accounts with Blank "LastLogonDates to OU=Blanks,OU=DisabledComputers, OU=Disabled, DC=NorwalkHealth,DC=org # 5) Moves Stale Computer account to OU=DisabledComputers, OU=Disabled, DC=NorwalkHealth,DC=org # 6) Creates a report of the Counts of OS's in Active directory After it runs. # 7) Captures Log information from the script and emails summary to list of users # Pre-Requisite: need to ha c:\Scripts folder or change paths; need to have edit LDap Paths for OU’s to move Disabled Computers to (66 and 87). # NOTES Custom Lines you will need to edit 14, 66, 87, 173 $EmailSmtpServer = "YourSMTPServer.mycorp.com" $ComputersDisabledLog = "" $EventMessage = "" # Initialize source for Application Event Log If ( -Not([System.Diagnostics.EventLog]::SourceExists('StaleComputerOBJPowershellScript'))) { New-EventLog -Source StaleComputerOBJPowershellScript -LogName Application } # Note the start of Process in Event log $EventMessage = "Started stale Computer account process: " + (get-date) Write-EventLog -LogName Application -Source StaleComputerOBJPowershellScript -EntryType information -EventID 60001 -Message $EventMessage $MailBody = ($EventMessage) + " `n " # Reset Counters $TCount = $CountXP = $Count2k = $win7 = $win2k3 = $win2k8 = $win2k12 = $win8 = $win10 = $CountBlank = 0 # create counts of Active Computers before changes $ActiveComputers = Get-ADComputer -Property Name,lastLogonDate,OperatingSystem,OperatingSystemServicePack -Filter * ForEach ( $Computer in $ActiveComputers) { if ($Computer.Enabled -eq $True) { Switch -Wildcard ($Computer.OperatingSystem) { "Windows XP*" {$CountXP = $CountXP + 1 } "Windows 2000 Server" {$Count2k = $Count2k + 1} "Windows 7*" {$win7 = $win7 + 1 } "Windows Server 2003" {$win2k3 = $win2k3 + 1 } "Windows Server 2008*" {$win2k8 = $win2k8 + 1 } "Windows Server 2012*" {$win2k12 = $win2k12 + 1 } "Windows 8*" {$win8 = $win8 + 1 } "Windows 10*" {$win10 = $win10 + 1 } $Null {$CountBlank = $CountBlank +1 } } $TCount = $TCount + 1 } } $ActiveBeforeCompTotal = "The Total # of Computer objects before running was " + ($TCount) + ". `nThere were a total of " + ($count) + " computers disabled!`n" + "There was " + ($CountXP) + " Windows XP, " + ($Count2k) + " Win2K server, " + ($win7) + " Windows 7, " + $win2k8 + " Windows 2008 server, " + $win2k3 + " Windows 2003 Server, " + $win2k12 + " Windows Server 2012, " + $win8 + " Windows 8, " + $win10 + " Windows 10, " + " and " + ($CountBlank) + "Blank Computers. `n `n `n" $MailBody = ($MailBody) + $ActiveBeforeCompTotal + " `n " # Set Stale limits $then = (Get-Date).AddDays(-90) # The 90 is the number of days from today since the last logon. # Reset counters $Count = $TCount = $CountXP = $Count2k = $win7 = $win2k3 = $win2k8 = $win2k12 = $win8 = $win10 = $CountBlank = 0 # Set Move to location for Blank Computer accounts $MoveToLocation = "OU=Blanks,OU=DisabledComputers, OU=Disabled, DC=MyCorp,DC=com" # Checking for Blank lastlogonDate Computer accounts $BlankComputers = Get-ADComputer -Property Name,lastLogonDate,OperatingSystem,OperatingSystemServicePack -Filter * foreach ($Computer in $BlankComputers) { if ($Computer.LastLogonDate -eq $Null ) { $ComputersDisabledLog = $ComputersDisabledLog + $Computer.Name + "`t" + $Computer.DistinguishedName + "`n" # !!!!!!! Perform Disable and move of Blamk Acounts !!!!!!!! Disable-ADAccount $Computer.distinguishedName Move-ADObject $Computer.distinguishedName -TargetPath $MoveToLocation $CountBlank = $CountBlank + 1 $Coount = $Count +1 } } # Checking for Stale Computer Accounts $MoveToLocation = "OU=DisabledComputers, OU=Disabled, DC=MyCorp,DC=com" $StaleComputers = Get-ADComputer -Property Name,lastLogonDate,OperatingSystem,OperatingSystemServicePack -Filter {lastLogonDate -lt $then} foreach ($Computer in $StaleComputers) { if ($Computer.Enabled -eq $True) { Switch -Wildcard ($Computer.OperatingSystem) { "Windows XP Professional" {$CountXP = $CountXP + 1 } "Windows 2000 Server" {$Count2k = $Count2k + 1} "Windows 7 Professional" {$win7 = $win7 + 1 } "Windows Server 2003*" {$win2k3 = $win2k3 + 1 } "Windows Server 2008*" {$win2k8 = $win2k8 + 1 } "Windows Server 2012*" {$win2k12 = $win2k12 + 1 } "Windows 8*" {$win8 = $win8 + 1 } "Windows 10*" {$win10 = $win10 + 1 } } $ComputersDisabledLog = $ComputersDisabledLog + $Computer.Name + "`t" + $Computer.DistinguishedName + "`n" # !!!!!!! Perform Disable and move of Stale Computer Accounts !!!!!!!! Disable-ADAccount -Identity $Computer.DistinguishedName Set-ADComputer -Identity $Computer.DistinguishedName -Description ("This account was disabled on " + (Get-Date) + " by the Automated Stale Computer Stript") Move-ADObject $Computer.DistinguishedName -TargetPath $MoveToLocation $Count = $Count + 1 } } # Building Event message and email Body $DisabledCompTotal = "There were a total of " + ($count) + " computers disabled!`n" + "There was " + ($CountXP) + " Windows XP, " + ($Count2k) + " Win2K server, " + ($win7) + " Windows 7, " + $win2k8 + " Windows 2008 server, " + $win2k3 + " Windows 2003 Server, " + $win2k12 + " Windows Server 2012, " + $win8 + " Windows 8, " + $win10 + " Windows 10, " + " and " + ($CountBlank) + " Blank Computers that were disabled. `n The Disabled Combuterojects were moved to " + ($MoveToLocation) + "`n `n `n" $MailBody = ($MailBody) + ($DisabledCompTotal) # Note the Disable Results of Process in Event log $EventMessage = ($DisabledCompTotal) + (get-date) Write-EventLog -LogName Application -Source StaleComputerOBJPowershellScript -EntryType information -EventID 60001 -Message $EventMessage # Write-EventLog -LogName Application -Source StaleComputerOBJPowershellScript -EntryType information -EventID 60001 -Message ("List of computers: " + " `n " + ($ComputersDisabledLog)) # Reset Counters $TCount = $CountXP = $Count2k = $win7 = $win2k3 = $win2k8 = $win2k12 = $win8 = $win10 = $CountBlank = 0 # Active Computers after the changes $ActiveComputers = Get-ADComputer -Property Name,lastLogonDate,OperatingSystem,OperatingSystemServicePack -Filter * ForEach ($Computer in $ActiveComputers) { if ($Computer.Enabled -eq $True) { Switch -Wildcard ($Computer.OperatingSystem) { "Windows XP Professional" {$CountXP = $CountXP + 1 } "Windows 2000 Server" {$Count2k = $Count2k + 1} "Windows 7 Professional" {$win7 = $win7 + 1 } "Windows Server 2003" {$win2k3 = $win2k3 + 1 } "Windows Server 2008*" {$win2k8 = $win2k8 + 1 } "Windows Server 2012*" {$win2k12 = $win2k12 + 1 } "Windows 8*" {$win8 = $win8 + 1 } "Windows 10*" {$win10 = $win10 + 1 } $Null {$CountBlank = $CountBlank +1 } } $TCount = $TCount + 1 } } $ActiveAfterCompTotal = "The Total # of Computer objects After running was " + ($TCount) + ". `nThere were a total of " + ($count) + " computers disabled!`n" + "There was " + ($CountXP) + " Windows XP, " + ($Count2k) + " Win2K server, " + ($win7) + " Windows 7, " + $win2k8 + " Windows 2008 server, " + $win2k3 + " Windows 2003 Server, " + $win2k12 + " Windows Server 2012, " + $win8 + " Windows 8, " + $win10 + " Windows 10, " + " and " + ($CountBlank) + " Blank Computers. `n `n `n" # Note the Total Active Computers in the Event log $EventMessage = ($ActiveAfterCompTotal) + (get-date) Write-EventLog -LogName Application -Source StaleComputerOBJPowershellScript -EntryType information -EventID 60001 -Message $EventMessage # add to and Build Body of Email $MailBody = ($MailBody) + "`n" + ( $ActiveAfterCompTotal) + " `n " + "List of computers move: " + " 'n " + ($ComputersDisabledLog) # Send email Message with application log activity related to the Script # Script run monly so this will give report for current month and previous. You can change this to whatever is best for you. $LogDate = (Get-Date).addDays(-60) # Create Report from Application log on this script. Export to a CSV $AttachementCSV = "C:\Scripts\staleComp.csv" Get-EventLog -logname Application -Source "StaleComputerOBJPowershellScript" -After $LogDate -Before (Get-Date) | export-csv -Path $AttachementCSV -Force #List of Disabled and moved Computer accounts + New Location $AttacheStaleCSV = "c:\Scripts\StaleCompList.txt" $ComputersDisabledLog | Out-File -filepath $AttacheStaleCSV # Send Mail Message to a list of Users $MailSubject = "Stale Computers Disabled on " + (Get-Date) Send-MailMessage -From "StaleComputerScript@Mycorp.com" -To "User1@MyCorp.com", "User2@mycorp.com" -Subject $MailSubject -Body $MailBody -SmtpServer $EmailSmtpServer -Attachments $AttachementCSV, $AttacheStaleCSV



    • Edited by Rayzavs1 Tuesday, June 9, 2015 1:16 PM text in wrong place
    Tuesday, June 9, 2015 1:13 PM
  • The point is that you cannot bypass elevation even if you are an administrator.  You must choose to run the whole script as an elevated administrator in order to write to the eventlog.

    The eventlog is not intended to be an application log.  For application logging you should use a file.  THeeventlog is usually used for specif notifications that are of a more global nature.

    You can do this without elevation:

    write-eventlog -LogName 'Windows PowerShell' -EventId 1 -Message 'My Test log' -Source powershell

    Only an elevated admin can create event source names.  They only need to be created once.


    \_(ツ)_/

    Tuesday, June 9, 2015 1:26 PM