WMI queries random access denied - powershell

Why does the Win32_Service WMI query randomly fail with deny access to my WMI Queries.
I'm running a Win32_Service WMI query daily against several different domains. Today I've noticed that the query failed in one DOMAIN because it was denied access. When I run the queries in a loop they fail at times that seem random to me. It will run successfully, fail once or twice and then run successfully again. So far I have only seen this occur in one of the domains I am checking.
This is the error message
Friday, December 09, 2016 2:33:26 PM
Get-WmiObject : Access is denied.
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At C:\junk\Untitled2.ps1:23 char:22
+ $Service_Data = Get-WmiObject `
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
This is the template for what I'm running
$loopDelay = 60
$userName = 'Domain1\LocalAdmin'
$pwd = 'Password'
$Sec_Pwd = $pwd | ConvertTo-SecureString -AsPlainText -Force
$Creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $Sec_Pwd
$Servers = #()
$Servers += "Server1.Domain1.org"
$Servers += "Server2.Domain1.org"
$Servers += "Server3.Domain1.org"
$Servers += "Server4.Domain1.org"
while (1 -eq 1)
{
Get-Date
$Service_Data = Get-WmiObject -Credential $creds -ComputerName $Servers Win32_Service |
where {$_.Name -eq "JunkTest"} |
select SystemName, State, Status
$Service_Data | Format-Table
"<Ctrl><C> to quit"
sleep 60
}

Related

PSSession search AD computers Powershell

Good afternoon everyone, I need to configure this script to run on AD machines, but I can only run it on the local machine, could you help me
I tried: $session = New-PSSession -ComputerName computer01
$events = Invoke-Command -ComputerName $session -ScriptBlock {`
param($days,$up,$down)
Get-EventLog `
-After (Get-Date).AddDays(-$days) `
-LogName System `
-Source EventLog `
| Where-Object {
$_.eventID -eq $up `
-OR `
$_.eventID -eq $down }
} -ArgumentList $NumberOfDays,$startUpID,$shutDownID -ErrorAction Stop
however it generated the error below:
Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects instead of
strings.
At line:68 char:15
+ ... $events = Invoke-Command -ComputerName $session -ScriptBlock {`
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.String[]:String[]) [Invoke-Command], ArgumentException
+ FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

I am trying to automate the config of TCPPort number 1433 on SQL Server 2016 and 2019 with a PS script

Inspired by this approach:
$pcName = $env:COMPUTERNAME
($dbmsName = Invoke-Sqlcmd -Query "SELECT ##servicename")
# Loading SQLPS environment
Import-Module SQLPS -DisableNameChecking -Force
# Initializing WMI object and Connect to the instance using SMO
($Wmi = New-Object ('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer') $pcName)
($uri = "ManagedComputer[#Name='$pcName']/
ServerInstance[#Name='$dbmsName']/ServerProtocol[#Name='Tcp']")
# Getting settings
($Tcp = $wmi.GetSmoObject($uri))
$Tcp.IsEnabled = $true
($Wmi.ClientProtocols)
# Setting IP properties
$wmi.GetSmoObject($uri + "/IPAddress[#Name='IPAll']").IPAddressProperties[1].Value="1433"
# Save properties
$Tcp.Alter()
# Restart service
Restart-Service -Name MSSQL* -Force
Start-Sleep -s 30
Whenever I try to test with lastest version of PowerShell(5.1.17763.2090) on both SQL Servers 2016 and 2019: I get an error:
PS C:\Windows\system32> ($Tcp = $wmi.GetSmoObject($uri))
Exception calling "GetSmoObject" with "1" argument(s): "Attempt to retrieve data for object failed for ManagedComputer
'DB2T-30223'."
At line:1 char:2
+ ($Tcp = $wmi.GetSmoObject($uri))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FailedOperationException
What am I missing?
I found this on stack - Use PowerShell To Enable TCP/IP in SQL Server Configuration Manager
It seems like the same error place '+ ($Tcp = $wmi.GetSmoObject($uri))'
$pcName = $env:COMPUTERNAME
$wmi = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $pcName
$wmiinstance = $wmi.ServerInstances | Where-Object { $_.Name -eq $wmiinstancename }
$tcp = $wmiinstance.ServerProtocols | Where-Object { $_.DisplayName -eq 'TCP/IP' }
$IpAddress = $tcp.IpAddresses | where-object { $_.IpAddress -eq $IpAddress }
$tcpport = $IpAddress.IpAddressProperties | Where-Object { $_.Name -eq 'TcpPort' }

Check/read registry key value on remote computer with local admin credential

How to check registry key value on computer which is not in domain??
I think that I must use local admin credential for this but I dont know how
I tried this:
$user = "admin"
$password = "pass" | ConvertTo-SecureString -asPlainText -Force
$computer = "computer"
$domain=$computer
$username = $domain + "\" + $user
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$password
$key = '\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters'
$valuename = 'DiskSpaceThreshold'
$wmi = Get-Wmiobject -list "StdRegProv" -namespace root\default -Computername $computer -Credential $Credential
$value = $wmi.GetStringValue($HKEY_Local_Machine,$key,$valuename).svalue
$wmi
$value
But the result:
Get-Wmiobject : Could not get objects from namespace root\default. Serwer RPC jest niedostępny. (Wyjątek od HRESULT: 0x800706BA) At line:12 char:8
+ $wmi = Get-Wmiobject -list "StdRegProv" -namespace root\default -Comp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : INVALID_NAMESPACE_IDENTIFIER,Microsoft.PowerShell.Commands.GetWmiObjectCommand You cannot call a method on a null-valued expression. At line:13 char:1
+ $value = $wmi.GetStringValue($HKEY_Local_Machine,$key,$valuename).sva ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH : ReturnValue : 6 uValue : PSComputerName :
So I tried something else
# file with computer name
$computers = Get-Content F:\IT\!Set_NTP_Time\ReadRegistry\servers.txt | ?{$_ -notmatch "^#"};
#Registry Hives
[long]$HIVE_HKROOT = 2147483648
[long]$HIVE_HKCU = 2147483649
[long]$HIVE_HKLM = 2147483650
[long]$HIVE_HKU = 2147483651
[long]$HIVE_HKCC = 2147483653
[long]$HIVE_HKDD = 2147483654
# registry
$HKLM = 2147483650
$main = "Localmachine"
$keyPath = "System\CurrentControlSet\Services\W32Time"
$keyName = "Start"
#$computer ='.'
$reg = [WMIClass]"ROOT\DEFAULT:StdRegProv"
$Key = "W32Time"
#$Value = "HistoryBufferSize"
#$results = $reg.GetDWORDValue($HKEY_LOCAL_MACHINE, $Key, $keyName)
#"Current History Buffer Size: {0}" -f $results.uValue
<#
Param($computer)
$HKEY_Local_Machine = 2147483650
$reg = [WMIClass]"\\$computer\ROOT\DEFAULT:StdRegProv"
$Key = "SOFTWARE\Wow6432Node\Symantec\Symantec Endpoint Protection\CurrentVersion\SharedDefs"
$ValueName = "DEFWATCH_10"
$results = $reg.GetStringValue($HKEY_LOCAL_MACHINE, $Key, $ValueName)
write $results.sValue
#>
# credentials
$user = "admin"
$user1 = "admin1"
$password = "pass" | ConvertTo-SecureString -asPlainText -Force
# Start processing
foreach($computer in $computers) {
$domain=$computer
$username = $domain + "\" + $user
$username1 = $domain + "\" + $user1
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$password
$Credential1 = New-Object System.Management.Automation.PSCredential -ArgumentList $username1,$password
try {
if (($computer -eq "comp1") -or ($computer -eq "comp2") -or ($computer -eq "name_of_computer") -or ($computer -eq "other_computer")) {
#$wmi = Get-Wmiobject -list "StdRegProv" -namespace root\default -Computername $computer -Credential $Credential1
#$value = $wmi.GetStringValue($HKLM,$keyPath,$keyName).svalue
#Write-Host -ForegroundColor DarkYellow $computer $value
#$value = Invoke-Command -Scriptblock {Get-Item $HKLM,$keyPath,$keyName} -Computername $computer -Credential $Credential1
$reg = Get-WmiObject -List -Namespace root\default -ComputerName $Computer -Credential $Credential1 | Where-Object {$_.Name -eq "StdRegProv"}
#$HKLM = 2147483650
#$value = $reg.GetStringValue($HKLM,$keyPath,$keyName).sValue
$value = $reg.GetDWORDValue($HKEY_LOCAL_MACHINE, $Key, $keyName)
Write-Host -ForegroundColor DarkYellow $computer $reg $value
} else {
#$wmi = Get-Wmiobject -list "StdRegProv" -namespace root\default -Computername $computer -Credential $Credential
#$value = $wmi.GetStringValue($HKLM,$keyPath,$keyName).svalue
#Write-Host -ForegroundColor DarkYellow $computer $value
#$value = Invoke-Command -Scriptblock {Get-Item $HKLM,$keyPath,$keyName} -Computername $computer -Credential $Credential
$reg = Get-WmiObject -List -Namespace root\default -ComputerName $Computer -Credential $Credential | Where-Object {$_.Name -eq "StdRegProv"}
#$HKLM = 2147483650
#$value = $reg.GetStringValue($HKLM,$keyPath,$keyName).sValue
$value = $reg.GetDWORDValue($HKEY_LOCAL_MACHINE, $Key, $keyName)
Write-Host -ForegroundColor DarkYellow $computer $reg $value
}
<#
if($value -eq 2)
{
Write-Host -ForegroundColor DarkYellow $computer "YES"
} else {
Write-Host -ForegroundColor Red $computer "NO"
}
#>
} catch {
Write-Host -ForegroundColor Red "$computer access denied.$_";
}
}
Result for this script
comp1 \COMP1\ROOT\default:StdRegProv System.Management.ManagementBaseObject
comp2 \COMP2\ROOT\default:StdRegProv System.Management.ManagementBaseObject
comp3 \COMP3\ROOT\default:StdRegProv System.Management.ManagementBaseObject
Personally, as I am used to use powershell remoting to gather information from remote machines, I would proceed like this:
Establish remote PS session
Run script on remote machine
Profit
So in your case, something like (If you are retrieving a value named DiskSpaceThreshold inside of HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters)
$user = "admin"
$password = "pass" | ConvertTo-SecureString -asPlainText -Force
$computer = "computer"
$domain=$computer
$username = $domain + "\" + $user
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$password
$session = New-PSSession $computer -Credential $Credential
$r = Invoke-Command -Session $session -ScriptBlock { Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters -Name "DiskSpaceThreshold" }
Remove-PSSession $session
Write-Host $r.DiskSpaceThreshold
The effect of trying to run the script from P-L user post
New-PSSession : [computer] Connecting to remote server computer failed with the following error message : WinRM cannot process the
request. The following error with errorcode 0x80090311 occurred while using Kerberos authentication: There are currently no
logon servers available to service the logon request.
Possible causes are:
-The user name or password specified are invalid.
-Kerberos is used when no authentication method and no user name are specified.
-Kerberos accepts domain user names, but not local user names.
-The Service Principal Name (SPN) for the remote computer name and port does not exist.
-The client and remote computers are in different domains and there is no trust between the two domains.
After checking for the above issues, try the following:
-Check the Event Viewer for events related to authentication.
-Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTT
PS transport.
Note that computers in the TrustedHosts list might not be authenticated.
-For more information about WinRM configuration, run the following command: winrm help config. For more information, see
the about_Remote_Troubleshooting Help topic.
At line:9 char:12
+ $session = New-PSSession $computer -Credential $Credential
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTran
sportException
+ FullyQualifiedErrorId : AuthenticationFailed,PSSessionOpenFailed
Invoke-Command : Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an argument that is
not null or empty, and then try the command again.
At line:10 char:30
+ $r = Invoke-Command -Session $session -ScriptBlock { Get-ItemProperty -Path HKLM ...
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand
Remove-PSSession : Cannot validate argument on parameter 'Id'. The argument is null. Provide a valid value for the argument,
and then try running the command again.
At line:11 char:18
+ Remove-PSSession $session
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Remove-PSSession], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.RemovePSSessionCommand
The username and password are good.

Powershell - Get MaxPasswordAge from multiple servers

PS Version: 5.0.10586.117
My requirement is to loop through a list of servers and using the "Get-ADDefaultDomainPasswordPolicy". I want to produce a list that has the server name and the MaxPasswordAge. I have verified that my credentials work on the remote serves. I don't want to change the MaxPasswordAge, I just want to know what it is for the specified server.
Server Name MaxPasswordAge
Server1.domain.com 90
Server2.domain.com 109
Server3.domain.com 109
The error that I frequently get is the following:
New-PSSession : [Server1.domain.com] Connecting to remote server Server1.domain.com failed with the following error message : The WS-Management service cannot process the request. The maximum number of concurrent shells for this user has been
exceeded. Close existing shells or raise the quota for this user. For more information, see the about_Remote_Troubleshooting Help topic.
At line:4 char:12
+ $Install = New-PSSession -ComputerName $SServer -Credential $Cred
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotingTransportException
+ FullyQualifiedErrorId : -2144108123,PSSessionOpenFailed
VERBOSE: Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
Here is the code I am using. Any help would be greatly appreciated. Should I use: Get-ADFineGrainedPasswordPolicy -Filter {Name -like "*"} instead?
$servers = get-content "C:\TEMP\servers.txt"
$Cred = Get-Credential
$Result = $()
ForEach ($Computer in $servers)
{
Try
{
$Session = New-PSSession -ComputerName $Computer -Credential $Cred
$Result = Invoke-Command -Session $Session -ScriptBlock {param($RName) Get-ADDefaultDomainPasswordPolicy -server $RName | Select $RName, maxpasswordage | Format-Table} -ErrorAction Stop -ArgumentList $Computer
Remove-PSSession $Session
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-Verbose -Message $ErrorMessage -Verbose
}
}
$Result | Export-Csv "C:\TEMP\ServerMaxPWAge.csv" -NoTypeInformation

Permissions for using gwmi win32_ntlogevent instead of get-eventog?

The problem I have: get-eventlog works (I tested by doing "run as" on the PoSH ISE). Get-WMIObject win32_ntlogevent does not. It's a perm issue of some sort. Help please.
Background:
I've built a script that uses gwmi win32_ntlogevent to pull event logs. (I chose it because it was an order of magnitude faster than either get-winevent or get-eventlog, even with filters).
However, I cannot reach some other servers in my environment. So I had the Servers group add a credential to connect under, that has some sort of Log Reader right. (not sure what they added)
Get-Eventlog:
$server = "myserver"
get-eventlog -ComputerName $server -logname "application"
(above returns results)
Get-WMIObject win32_ntlogevent does not. Neither with
Get-WmiObject win32_ntlogevent -ComputerName $server
or
$time = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime('2015/05/01 5:00:00am')
$EventQuery = #"
select
Logfile, RecordNumber, Timegenerated, TimeWritten, EventCode, EventType, Type, Category, CategoryString, SourceName, InsertionStrings, ComputerName, User, Message
from Win32_NTlogEvent
where timewritten >='$time'
and LogFile = 'system'
"# #this line must be un-recessed
gwmi -computername $server -Query $EventQuery
Instead, I get:
gwmi : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:10 char:1
+ gwmi -computername "myserver" -Query $EventQuery
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Thanks!