Setting File Owner to user in a non-trusted domain via PowerShell - powershell

I am trying to set the owner of a file to a SID from another another domain.
This domain is Non-Trusted so the following won't work.
PS > (Get-Acl .).SetOwner([System.Security.Principal.NTAccount]'TESTWORLD\barry')
Exception calling "SetOwner" with "1" argument(s): "Some or all identity references could not be translated."
At line:1 char:1
+ (Get-Acl .).SetOwner([System.Security.Principal.NTAccount]'TESTWORLD\barry')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException
I am able to get the SID for the user from the other domain like so:
$c = Get-Credentials TESTWORLD.INVALID\AdminUser
$dc = Get-ADDomainController -Discover -DomainName TESTWORLD.INVALID -Service PrimaryDC | %{$_.HostName}
$sid = Get-ADUser -Filter {Name -eq "barry"} -Server $dc -Credential $c | %{$_.SID}
I then want to set this SID to be the owner of that file. How is that possible?

If DCOM traffic is allowed to the remote computer, try the following. You'll need to set $Path to the local path for the remote system. If you're using alternate credentials, provide a Credential value in the $OptionalCred hash table:
Try this:
$Path = "C:\Folder"
$OwnerSID = # SID string goes here #
$Computer = $env:ComputerName
$OptionalCred = #{
# Don't use this running against local machine
#Credential = Get-Credential TESTWORLD.INVALID\AdminUser
}
$EscapedPath = [regex]::Escape($Path)
$FileSecuritySetting = Get-WmiObject Win32_LogicalFileSecuritySetting -Filter "Path='$EscapedPath'" -ComputerName $Computer #OptionalCred
$Win32SD = $FileSecuritySetting | Invoke-WmiMethod -Name GetSecurityDescriptor | select -ExpandProperty Descriptor
$NewOwner = ([wmiclass]"Win32_Trustee").PSBase.CreateInstance()
$NewOwner.SIDString = $OwnerSID
$Win32SD.Owner = $NewOwner
Invoke-WmiMethod -Path $FileSecuritySetting.__PATH -Name SetSecurityDescriptor -ArgumentList $Win32SD #OptionalCred

Related

Getting Registry Key of all machines in the domain

sorry if it's a silly question. I'm trying to get the "EnableDCOM" Registry Key of all the machines on the domain and disable them. I'm kinda stuck with getting the status of the registry key.
Get-Adcomputer -Filter * | Get-itemProperty -path HKLM:\Software\Microsoft\OLE -name "EnableDCOM"
Here is the error:
Get-ItemProperty : Cannot process argument transformation on parameter 'Credential'. userName
At line:1 char:28
... -filter * | Get-ItemProperty -path HKLM:\Software\Microsoft\OLE -name ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidData: (CN=DAYGROUP-PCI...=daygroup,DC=ca:PSObject) [Get-ItemProperty], ParameterB
indingArgumentTransformationException
FullyQualifiedErrorId : ParameterArgumentTransformationError,Microsoft.PowerShell.Commands.GetItemPropertyComman
d
After trying to use the domain admin credential:
The provider does not support the use of credentials. Perform the operation again without specifying credentials.
At line:1 char:1
get-adcomputer -filter * | Get-ItemProperty -path HKLM:\Software\Micr ...
+ CategoryInfo : NotImplemented: (:) [], PSNotSupportedException
+ FullyQualifiedErrorId : NotSupported
This code can help you. Don`t forget to specify different credential if needed.
$ADComputers = ( Get-ADComputer -Filter * ).Name
$ResultArray = #()
foreach ( $Computer in $ADComputers ){
#Maybe you need specify different credential -Credential $cred
$Value = Invoke-Command -ComputerName $Computer -ScriptBlock {
$Value = Get-ItemPropertyValue -path 'HKLM:\Software\Microsoft\OLE' -name 'EnableDCOM'
return $Value
}
$PSO = [PSCustomObject]#{
Computer = $Computer
Value = $Value
}
$ResultArray += $PSO
}
$ResultArray

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 Script reading file into array

I have a script I'm working on. I want it to read in a column named ComputerName and one named UserName.
My CSV file looks like this:
ComputerName | Username
computer01 | user1
computer02 | user2
The Pipes are representing cells in excel.
Here's my script:
$computerName = #()
$userName = #()
Import-Csv C:\test\script\Computername_username_test.csv -Delimiter "|" |`
ForEach-Object
{
$computerName += $_.ComputerName
$userName += $_.UserName
}
$destination = New-Item -ItemType Directory -Path C:\test\$userName\dictionary_Files\ -force
$fileList = Get-WmiObject -Class CIM_DataFile -Filter "Drive='C:' And Extension='dic'" -Computername $computerName
foreach ($file in $fileList)
{
$drive, $path = $file.Name.Split('\',2)
$drive = $drive -replace ':','$'
$remoteFile = "\\$computerName\$drive\$path"
Write-Verbose "Copy $remoteFile to $destination"
Copy-Item $remoteFile -Destination $destination -Confirm
}
My goal is to search the C drive of the remote computer for all files with the .dic extension and copy them to a location inside a folder that is named the same as their username from the excel sheet.
When I run this I'm getting the following:
PS C:\Test\Script> C:\Test\Script\DicFiles03_importCSV.ps1
cmdlet ForEach-Object at command pipeline position 2
Supply values for the following parameters:
Process[0]:
$computerName += $_.ComputerName
$userName += $_.UserName
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null, empty, or an element of the argument
collection contains a null value. Supply a collection that does not contain any null values and then try the command again.
At C:\Test\Script\DicFiles03_importCSV.ps1:13 char:102
+ ... -Filter "Drive='C:' And Extension='dic'" -Computername $computerName
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Thank you for your help.
I'm think its because you have your { after the foreach-object on the next line powershell is a scripting language so its particular about line endings.

Registering A record in DNS remotely using powershell

Below is my script, Please let me know if am missing something.
#Script to add DNS 'A' Records 'PTR' Records to DNS Servers
$dns = "afidc1.XXXXXXX.com" # Your DNS Server Name
$Zone = "XXXXXXX.com" # Your Forward Lookup Zone Name
$IP = "X.X.X.X"
$Name = "pweb17s1"
$localuser = "XXXXXX\mayigi01"
$localpass = "XXXXXX"
Enter-PSSession –ComputerName $dns -GuestCredential $localuser $localpass
Import-Module DnsServer
Add-DnsServerResourceRecordA –ComputerName $dns -Name $Name -IPv4Address $IP -ZoneName $Zone
Below is the error am facing:
Enter-PSSession : A positional parameter cannot be found that accepts argument 'â€ComputerName 'afidc1.XXXXX.com'
-GuestCredential XXXXX\mayigi01 XXXXX
Import-Module DnsServer
Add-DnsServerResourceRecordA â€ComputerName'.
At C:\Users\devoops!\Desktop\dns.ps1:9 char:1
+ Enter-PSSession –ComputerName 'afidc1.XXXXX.com' -GuestCredential $localus ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Enter-PSSession], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.EnterPSSessionCommand
I used the ISE:
just copy it from here maybe?
#Script to add DNS 'A' Records 'PTR' Records to DNS Servers
$dns = "afidc1.XXXXXXX.com" # Your DNS Server Name
$Zone = "XXXXXXX.com" # Your Forward Lookup Zone Name
$IP = "X.X.X.X"
$Name = "pweb17s1"
$localuser = "XXXXXX\mayigi01"
$localpass = "XXXXXX"
Enter-PSSession -ComputerName $dns -GuestCredential $localuser $localpass
Import-Module DnsServer
Add-DnsServerResourceRecordA –ComputerName $dns -Name $Name -IPv4Address $IP -ZoneName $Zone