Script to convert multiple SID to readable username - powershell

I have a text file that contain below detail, so I need help on the script that can convert multiple SID to the readble username, but I'm really doubt with the coding.
Window based permission file contain information as below sample when open with notepad
[/]
S-1-5-21-1449722967-1661817991-10773629-12231=rw
S-1-5-21-1449722967-1661817991-10773629-15527=rw
[AM_ATTG:/]
S-1-5-21-1449722967-1661817991-10773629-1207=rw
Between, I have found the script to convert SID from How can I use powershell to change sid in csv to user?
Therefore, I save the file into .csv and put heading for first column as User and second column as Permission
User Permission
[/]
S-1-5-21-1449722967-1661817991-10773629-12231 rw
S-1-5-21-1449722967-1661817991-10773629-15527 rw
[AM_ATTG:/]
S-1-5-21-1449722967-1661817991-10773629-1207 rw
but I getting the error below when tried the first powershell script, your reply on any hints about my post is very much appreciated.
Import-Csv : Cannot process argument because the value of argument "name" is invalid. Change the value of the "name" argument and run the operation again.
At line:1 char:19
+Import-Csv <<<< .\sid.csv | ForEach-Object{
+ CategoryInfo : InvalidArgument: (:) [Import-Csv], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.ImportCsvCommand

VBScript flavor:
sidList = Array( "S-1-5-21-1449722967-1661817991-10773629-12231=rw" _
, "S-1-5-21-1449722967-1661817991-10773629-15527=rw" _
, "S-1-5-21-1449722967-1661817991-10773629-1207=rw" _
)
Set wmi = GetObject("winmgmts://./root/cimv2")
For Each sid In sidList
Set obj = wmi.Get("Win32_SID.SID='" & Replace(sid, "=rw", "") & "'")
WScript.Echo obj.ReferencedDomainName & "\" & obj.AccountName
Next
Update: You could implement the script as a filter like this:
Set wmi = GetObject("winmgmts://./root/cimv2")
Do Until WScript.StdIn.AtEndOfStream
line = Trim(WScript.StdIn.ReadLine)
If UCase(Left(line, 2)) = "S-" Then
Set obj = wmi.Get("Win32_SID.SID='" & Replace(sid, "=rw", "") & "'")
WScript.StdOut.WriteLine obj.ReferencedDomainName & "\" & obj.AccountName
End If
Loop
Run the filter like this:
type input.txt | cscript //NoLogo filter.vbs > output.txt
Note that you must use cscript.exe or you wont have access to WScript.StdIn or WScript.StdOut.

I suggest you make the csv file look like that (comma delimited):
Sid,Permission
S-1-5-21-1449722967-1661817991-10773629-12231,rw
S-1-5-21-1449722967-1661817991-10773629-15527,rw
S-1-5-21-1449722967-1661817991-10773629-1207,rw
Then you can do:
Import-Csv SID.csv |
Select-Object Sid,Permission,#{n='User';e={(New-Object System.Security.Principal.SecurityIdentifier $_.Sid).Translate([System.Security.Principal.NTAccount]).Value}}

Related

PowerShell - Add-Content- Unable to add multiple vars to a file

I'm trying to add an expression to a log file which contains Date,Time some data separated by ";". Unfortunately I get an error every time I change the position of the items in the -value brackets.
Whats seems to be wrong?
This is the code :
Add-Content -path C:\...\outlog.txt -Value($Date + ';' + $Time + ';Checked;' + $strFileName)
This is the error :
Cannot convert argument "1", with value: ";", for "op_Addition" to type "System.TimeSpan": "Cannot convert
value ";" to type "System.TimeSpan". Error: "String was not recognized as a valid TimeSpan.""
At C:\...\Untitled1.ps1:8 char:64
+ ... \outlog.txt -Value($($Date + ';' + $Time + ';'+ $str))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Try this -
Add-Content -path C:\...\outlog.txt -Value("$Date; $Time; Checked; $strFileName")
If you look at get-help Add-Content -full, and look at the -value parameter, you will see -
-Value <Object[]>
Specifies the content to be added. Type a quoted string, such as "This data is for internal use only", or
specify an object that contains content, such as the DateTime object that Get-Date generates.
You cannot specify the contents of a file by typing its path, because the path is just a string, but you can
use a Get-Content command to get the content and pass it to the Value parameter.
Required? true
Position? 1
Default value None
Accept pipeline input? True (ByPropertyName, ByValue)
Accept wildcard characters? false
It says that it expects a quoted string or an object that contains content. It was missing in your case and hence the + operator was trying to add $date and time.

Invoke-expression on a previous script to add parameters to it from a csv

I'm learning powershell only from few month, and I'have been asked to write a script that outsides my actual knowledge.
I have a script which work perfectly when I have to extract user from ONE AD group. My probleme here is that this script accept only one parameter and I have been asked this week to extract over 1000 groups...)
.\myscript.ps1 ADgroup
What I want to do :
1. I get an extract in CSV so I'd like to put in parameters all these groups to my script
2. I want to generate a file text of the result but I am not sure which is the best way to do that in this case.
So Here is my code
$grouplist=IMPORT-CSV C:\Myfile\Mytest\liste.csv
foreach ($group in $grouplist) {
Invoke-Expression .\membre_group_AD_V2.ps1 $group
}
My CSV test had just to group to run my test, I get the same kind of error on each group
Invoke-Expression : Impossible de trouver un paramètre positionnel acceptant l'argument « #{grouplist=Administrators} ».
Au caractère C:\myfile\Mytest\script\dev\bouclage_membre_group_AD_V2.ps1:36 : 2
+ Invoke-Expression .\membre_group_AD_V2.ps1 $group
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument : (:) [Invoke-Expression], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeExpressionCommand
If required I can try to translate this error. If you can help to improve my knowledge it could be great! Thank you for tanking time to read this.
It seems that you have a "grouplist" header in your CSV file. I assume it looks something like this:
"grouplist"
"Administrators"
"Other Group Name"
Now, when you use Import-Csv, all rows are read into an object with a single NoteProperty per column, named after the headers in the csv file.
So in your case, each object in $grouplist has a grouplist property that contains the name - this is the property value you want to pass as an argument to your script:
$grouplist=Import-Csv C:\Myfile\Mytest\liste.csv
foreach ($group in $grouplist) {
.\membre_group_AD_V2.ps1 $group.grouplist
}
Assuming that the output from membre_group_AD_V2.ps1 is already what you expect, use the Out-File cmdlet with -Append to write it to the same text file:
$grouplist=Import-Csv C:\Myfile\Mytest\liste.csv
$OutfilePath = "C:\Myfile\membre_group_out.txt"
foreach ($group in $grouplist) {
.\membre_group_AD_V2.ps1 $group.grouplist | Out-File $OutfilePath -Append -Encoding utf8
}
If not, you'll have to show us the membre_group_AD_V2.ps1 script

powershell CategoryInfo NotSpecified and newlines

I have an app that prints text to stderr, so to save to a file, I do this:
.\NGPQUERY.exe -spoof -stages -diag 2> c:\foo.txt
None of the text is special characters, other than crlf at the end of lines.
In DOS, the output is fine.
In powershell the output is almost fine.
The first line of text is this:
RTE Routings for BRI to LED - 00:
I get this error message at the top of the output:
NGPQUERY.exe : RTE Routings for BRI to LED - 00:
At line:1 char:15
+ .\ngpquery.exe <<<< -spoof -stages -diag 2> e:\foo
+ CategoryInfo : NotSpecified: (RTE Routings for BRI to LED - 00: :String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Then throughout the output, line feeds are added at seemingly random locations. So my question is how do I get rid of the error and the random line feeds.
Also powershell outputs file that is twice as large as the dos file, I'm guessing its unicode. So I would like to know the best way get an ansi output too.
If you only need STDERR, this should be enough:
$oPsi = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$oPsi.FileName = "NGPQUERY.exe"
$cArgs = #("-spoof", "-stages", "-diag")
$oPsi.Arguments = $cArgs
$oPsi.CreateNoWindow = $true
$oPsi.UseShellExecute = $false
$oPsi.RedirectStandardError = $true
$oProcess = New-Object -TypeName System.Diagnostics.Process
$oProcess.StartInfo = $oPsi
[Void]$oProcess.Start()
$sStdErr = $oProcess.StandardError.ReadToEnd()
[Void]$oProcess.WaitForExit()
$sStdErr | Out-File -Encoding "ASCII" -FilePath "C:\foo.txt"
This is an old question, but I got here because I had a similar problem and found the easiest solution to be to call cmd.exe and surround the command in quotes, to prevent Powershell from interpreting it. So in the above case that would be:
cmd.exe /c ".\NGPQUERY.exe -spoof -stages -diag 2> c:\foo.txt"

trim input from reg query

Windows XP machine:
reg query "\\COMPUTER_NAME\HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\WinLogon" /v DefaultUserName
output of: DefaultUserName REG_SZ ajstepanik
.
Windows 7 machine
reg query "\\COMPUTER_NAME\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" /v LastLoggedOnUser
output of: LastLoggedOnUser REG_SZ GHS_NTDOMAIN\ajstepanik
.
.
I was wondering if it were possible to trim this down so I would be left with GHS_NTDOMAIN\ajstepanik ... or even better, if I could just get the username which in this example, is ajstepanik
The reason for pulling the name and storing it, is that I can take that and plug it into other commands.
.
.
EDIT for additional help (win7):
$reg1 = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $tag1)
$key1 = $reg1.OpenSubKey('Microsoft\Windows\CurrentVersion\Authentication\LogonUI')
$user1 = $key1.GetValue('LastLoggedOnUser') -replace '^.*?\\'
echo $user1
returns error:
You cannot call a method on a null-valued expression.
At C:\Users\ajstepanik\Desktop\test.ps1:30 char:1
+ $user1 = $key1.GetValue('LastLoggedOnUser') -replace '^.*?\\'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I'd drop reg.exe entirely and read the remote registry like this:
$rhost = 'COMPUTER_NAME'
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $rhost)
$key = $reg.OpenSubKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon')
$user = $key.GetValue('DefaultUserName') -replace '^.*?\\'
It's a cleaner approach, since GetValue already produces the actual value. You don't have to parse it out of some other string before you can do things with it.
Seems simple enough:
(reg query "\\%tag%\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" /v LastLoggedOnUser).split('\')[1]
It's giving you back a string. Just split it at the backslash. and take the second element.
You can use Microsoft .NET Framework types to query the registry remotely, and get an object result. Check out the Remote Registry module for PowerShell: http://archive.msdn.microsoft.com/PSRemoteRegistry
That being said, you can parse the output of your command above, like so:
$Output = reg query "\\%tag%\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" /v LastLoggedOnUser
$Output -join '' -match '\w+\\\w+$';
$matches[0];
If you want to take it one step further, you can parse the domain and username via regex "named groups" like so:
$output -join '' -match '(?<domain>\w+)\\(?<username>\w+)$';
$matches.username;
$matches.domain;

Method Invocation failed system.string error

Morning,
I'm trying to use a CSV file with a list of users and automate the process to set an AD users extensionAttribute15 back to the "notset" value.
I use a similar code to populate the attribute, the CSV file consists of just two things, the users LAN ID and the value for the attribute.
Populating the field is not the problem, changing the values back to "not set" has been.
Here is the code I am using.
Import-module ActiveDirectory
Import-CSV "code.csv" | % {
$User = $_.cn
$user.Put(“extensionAttribute15”, #())
$user.SetInfo()
}
and here are the errors.
Method invocation failed because [System.String] doesn't contain a method named 'Put'.
At attribute.ps1:4 char:10
+ $user.Put <<<< (“extensionAttribute15”, #())
+ CategoryInfo : InvalidOperation: (Put:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'SetInfo'.
At attribute.ps1:5 char:14
+ $user.SetInfo <<<< ()
+ CategoryInfo : InvalidOperation: (SetInfo:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Any ideas what the problem could be?
Thanks,
When you read in a CSV file, the resulting objects are just simple property bags. They don't support any special methods, they just hold flat data. There is nothing in these objects that isn't present in the text of the CSV file itself.
If you want to obtain a rich object which has Active Directory context and capabilities, you will need to obtain one from a cmdlet in the ActiveDirectory module.
Something like this is probably along the lines you need
Import-module ActiveDirectory
Import-CSV "code.csv" | % {
$user = Get-ADUser $_.cn # get a rich object from the AD module, by passing a string
$user.Put(“extensionAttribute15”, #())
$user.SetInfo()
}