windows service running under non-local admin user not able to get results from WMI agent - powershell

We have a windows service which is running under a account that is not part of local admin. With in the service we call a powershell file using processstartinfo. With in powershell file we call the WMI class
"$AVGCPU = Get-WmiObject win32_processor | Measure-Object -property LoadPercentage -Average | Select-object -expand Average"
The above code always returns 0. When i make the user as local admin then the cpu usage value is returned. Also when i run the same code in powershell launched under the same user account (without giving local admin privileges), i am able to get the value for CPU usage. Its only when the cmdlets is called from windows service i am getting this problem. Due to security restriction, i cannot make the user as local administrator. Any idea what rights should be given to the user that WMI class return value when called from windows service.

Related

Why Search-ADAccount is giving different results when Run as Administrator

I am connected as Domain Admin to my DC. When I run the following command in a PowerShell windows, it finds 2 users
Search-ADAccount -UsersOnly -AccountInactive -TimeSpan 90.00:00:00 -SearchBase "OU=myOu,DC=myDomain,DC=local"
| Where {$_.enabled} | Sort-Object -Property LastLogonDate
When I run the same command in a PowerShell Run as Administrator, it finds 28 users
it looks like if the PowerShell console is started as Administrator, it can affect the cmdlet's ability to read certain Object and I do not understand why.
Has someone has seen such behavior and can explain why please?
You can temporarily disable User Account Control (UAC) and then run your PowerShell command which should return the expected results even if you don't invoke Run as Administrator. That's your quick answer.
The reason is because UAC is not giving you the admin token which you think you already have (but don't) when you run PowerShell as a non-administrator (even though you are logged into the DC as a domain administrator). When UAC is bypassed, such as (1) when it's disabled, (2) has its security level lowered enough, or (3) you invoke Run as Administrator, you have all the rights to read all the properties in AD and all the expected data returns. But in this case PowerShell will not show values for properties when there is no admin token attached because UAC is enabled on the DC. It will simply show no values/data (as opposed to throwing an error). There's a Reddit thread on this here.

Environment variable clientname gives no result on domain users

I am having trouble getting the expected result for environmental variable clientname in PowerShell.
On Windows 2016 Server through RDP session.
I run the request $env:clientname with a domain user and get no result
I run the request $env:clientname with a local user and get expected connected terminal Hostname.
This is affecting functions on apps running through TS with domain users.
Domain user result:
Local user result:
Read this (very old) MS article
https://support.microsoft.com/en-us/help/2509192/clientname-and-sessionname-enviroment-variable-may-be-missing
It still applies.
Possible fix:
$sessionID = (Get-Process -PID $pid).SessionID
$sessionCLIENTNAME = (Get-ItemProperty -path ("HKCU:\Volatile Environment\" + $sessionID) -name "CLIENTNAME").CLIENTNAME

Get-WinEvent via Powershell remoting

I have a non-admin access to a server. I'm allowed to connect via RDP, and to use PowerShell remoting. When I invoke the following PowerShell command from an RDP session:
Get-WinEvent -MaxEvents 100 -Provider Microsoft-Windows-TaskScheduler
I get 100 records, as expected.
When I do the same via PowerShell remoting, by invoking the following from my local machine:
invoke-command -ComputerName myserver {Get-WinEvent -MaxEvents 100 -Provider Microsoft-Windows-TaskScheduler }
I get an error:
No events were found that match the specified selection criteria.
CategoryInfo : ObjectNotFound: (:) [Get-WinEvent], Exception
FullyQualifiedErrorId : NoMatchingEventsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
Any idea why? The remote PowerShell session should be running under identical credentials, right?
EDIT: whoami does show a difference in the security context between RDP logon and PowerShell remoting - the group set is different. In the RDP logon session, there are the following groups in the token:
BUILTIN\Remote Desktop Users
NT AUTHORITY\REMOTE INTERACTIVE LOGON
while in the remoted one, there's
CONSOLE LOGON
That could account for the discrepancy in rights...
EDIT: from the registry, it looks like the task scheduler log somehow is a part of the System log. According to MS KB article Q323076, the security descriptor for the System log can be found under HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System, value CustomSD. I can't check the server in question, but on another server where I'm an admin, there's no CustomSD under that key. Under HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System\Microsoft-Windows-TaskScheduler, neither. Only the Security log gets a CustomSD. The next question is, where's the default SD?
Permissions on the actual log file at C:\Windows\System32\winevt\LogsMicrosoft-Windows-TaskScheduler%4Operational.evtx are irrelevant, the access is being mediated by the EventLog service anyway.
If you are not an administrator on the remote computer, and invoke-command -ComputerName myserver {whoami /all} tells you are who you expected to be.
You will need to be part of Event Log Reader group on the remote computer.
As well as Remote Management Users group, which I believe you already are.
If you need to read security logs, you will also need Manage auditing and security log under Local Security Policy -> Security Settings -> Local Policies -> User Rights Assignment
According to Default ACLs on Windows Event Logs # MSDN blog, in Windows Server 2003+, the default ACL for the System log goes:
O:BAG:SYD:
*(D;;0xf0007;;;AN) // (Deny) Anonymous:All Access
*(D;;0xf0007;;;BG) // (Deny) Guests:All Access
(A;;0xf0007;;;SY) // LocalSystem:Full
(A;;0x7;;;BA) // Administrators:Read,Write,Clear
(A;;0x5;;;SO) // Server Operators:Read,Clear
(A;;0x1;;;IU) // INTERACTIVE LOGON:Read <===================
(A;;0x1;;;SU) // SERVICES LOGON:Read
(A;;0x1;;;S-1-5-3) // BATCH LOGON:Read
(A;;0x2;;;LS) // LocalService:Write
(A;;0x2;;;NS) // NetworkService:Write
Does NT AUTHORITY\INTERACTIVE LOGON include RDP logon? I've found a forum message that says so, but I'd better find a doc to that effect...
The article claims this ACE comes "straight from the source code". So it's hard-coded in the service, with a chance to change via the registry.
You need local admin rights to open a powershell session.
But there is a workaround/alterative here:
https://4sysops.com/archives/powershell-remoting-without-administrator-rights/
I had the weirdest variation of this problem, was driving me nuts !
Remoting from a server W2008r2 (logged on as domain admin, inside interactive powershell session) to workstation Win7 to get logon/logoff events :
invoke-command -computername $pc {Get-WinEvent -FilterHashtable #{logname='
Security';Id=#(4624,4634)}}
-> No events were found that match the specified selection criteria.
But it does work when outputting an empty string in the scriptblock before the Get-Winevent :
invoke-command -computername $pc {"";Get-WinEvent -FilterHashtable #{lognam
e='Security';Id=#(4624,4634)}}
TimeCreated ProviderName Id Message PSComputerName
----------- ------------ -- ------- --------------
19/03/2018 11:51:41 Microsoft-Windows-Se... 4624 An account was succe... b25_x64
19/03/2018 11:51:41 Microsoft-Windows-Se... 4624 An account was succe... b25_x64
Stumbled upon this fix after trying everything: Enter-Pssession, New-Pssession, using -credential parameter to pass a predefined credential to invoke-command, to get-winevent, to both. Nothing worked, gave "No events..." in every combination.
Then I inserted a $cred inside the scriptblock to show the passed on credential for debugging, and suddenly I got the events I was looking for...

How to check if a server is running windows 2003 or Windows 2008 by checking its RDP screen, through script?

We have recently acquired a small firm having 1500 servers on which our team doesn't has access as of now although they are in domain. We need to find out how many servers are running Windows 2k3 and how many are Windows 2k8.
I know the RDP screen of both of these versions are different , for example: if we RDP a Win2k3 machine, it gives a warning notice first and once we click Ok, it takes us to the credentials screen , but in case of Win2k8, it directly takes us to Crendentials which is a proof of the OS on the server. Doing this manually for 1500 servers is a time consuming task.
Can we implement this RDP screen logic using a script to find out the Windows OS version.
I can imagine an Algorithm something like that:
Enter server name.
Invoke mstsc for that server
Verify if the dialogue box is a direct prompt for credentials or not?
If so, print Windows 2k8, else 2k3/2k.
If this logic successful on one server, I can use it in a foreach loop for all servers and export in in Excel.
With 1500 servers I'm going to assume that you have an Active Directory in place. In that case you should be able to simply run a query against AD to retrieve the desired information:
Import-Module ActiveDirectory
$server = 'somehostname'
$dc = '...' # domain controller of trusted domain
$fltr = "OperatingSystem -like '*server*'"
Get-ADComputer -Filter $fltr -Property OperatingSystem -Server $dc |
Where-Object { $_.Enabled } |
Select-Object Name, OperatingSystem |
Sort-Object OperatingSystem, Name
Pipe the result into Export-Csv to create a CSV file that you can import into Excel.

Windows Network adaptor disable enable via Powershell

My network card is rubbish and until I get a new one I need a quickfix. My idea was to have a program ping my router and when the ping failed 3 or 4 times, it would reset the network adaptor for my wifi card, however I do not know the command line commands to do this!
I found the following in a stackoverflow question:
$adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.Name -like "*Wireless*"}
$adaptor.Disable()
$adaptor.Enable()
However to run this the script needs to be running under admin privileges and I do not know how to fix that without manually launchign powershell to execute the script
This post shows how to elevate PowerShell scripts to Administrator access:
Elevate Powershell scripts
To do it, you create a scheduled task (without a set schedule), and set it to run elevated. Then, give your users rights to execute that task. This blog post describes the process in more detail:
http://huddledmasses.org/vista-setuid-how-to-elevate-without-prompting/
In addition, here is a blog post that goes over the Win32_NetworkAdapter class, and how to use it in PowerShell, in detail:
Using PowerShell to Manage Network Interfaces and Windows Services
http://rickgaribay.net/archive/2008/09/26/using-powershell-to-manage-network-interfaces-and-windows-services.aspx