I have a PowerShell function that will enable auditing on the Perflogs folder. The function works just fine on a Windows PC with an English installation language. But when I use it on a Danish version it fails because "Everyone" doesnt exit on a Danish installation. On a Danish installation "Everyone" is called "Alle"
So instead of using everyone, then I would like to use the SID "S-1-1-0"
S-1-1-0 = Everyone/World link
But for some reason this also does not work. Does anyone have a clue about this and why I can’t do this?
function AddAuditToFile {
param
(
[Parameter(Mandatory=$true)]
[string]$path
)
Get-Acl $path -Audit | Format-List Path,AuditToString | Out-File -FilePath 'file_before.txt' -Width 200 -Append
$File_ACL = Get-Acl $path
$AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule("S-1-1-0","CreateFiles,Modify,AppendData”,"none","none",”Success")
$File_ACL.AddAuditRule($AccessRule)
$File_ACL | Set-Acl $path
Get-Acl $path -Audit | Format-List Path,AuditToString | Out-File -FilePath 'file_after.txt' -Width 200 -Append}
I call the function like this:
AddAuditToFile "C:\Perflogs"
Use the SecurityIdentifier class to translate the SID:
$everyoneSid= New-Object System.Security.Principal.SecurityIdentifier "S-1-1-0"
$everyoneSidName= $everyoneSid.Translate([System.Security.Principal.NTAccount])
$everyoneSidName.Value
This will output the actual everyone group name depending on the actual machine.
Gungnir from Spiceworks found the solution.
I had to translate the SID and make a variable and then use the variable
$AccountSID = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList 'S-1-1-0'
$AccountName = $AccountSID.Translate([System.Security.Principal.NTAccount]).Value
$AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule -ArgumentList ($AccountName,'CreateFiles,Modify,AppendData','none','none','Success')
Related
I want to take this part
REGISTRATION_ELI_20221222_071008.csv
from this PowerShell output of Posh-SSH Get-SFTPChildItem
Name REGISTRATION_ELI_20221222_071008.csv, Length 0, User ID 1142,
Group ID 1220, Accessed 12/21/2022 3:00:47 PM, Modified 12/21/2022
3:00:47 PM
How can I get it?
#Date
$time = (Get-Date).ToString("yyyyMMdd")
#Setting credentials for the user account
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("gomgom", $password)
$SFTPSession = New-SFTPSession -ComputerName 172.16.xxx.xxx -Credential $Credential -AcceptKey
# Set local file path and SFTP path
$LocalPath = "D:\WORK\Task - Script\20221010 - AJK - ITPRODIS380 - upload file csv ke sql server\csvfile"
$FilePath = Get-SFTPChildItem -SessionId $SFTPSession.SessionId "/Home Credit/Upload/" | Select-String -Pattern "REGISTRATION_ELI_$([datetime]::Now.toString('yyyyMMdd'))"
$FilePath
Remove-SFTPSession $SFTPSession -Verbose
Do not parse the name from the string dump of the file object.
The Posh-SSH Get-SFTPChildItem returns SSH.NET SftpFile, which has Name attribute:
$FilePath.Name
(though then the $FilePath is actually a confusing variable name, as it's an object, not a mere path string)
You can dig into the Regex library and extract it out using Regex
$test = "Name REGISTRATION_ELI_20221222_071008.csv, Length 0, User ID 1142, Group ID 1220, Accessed 12/21/2022 3:00:47 PM, Modified 12/21/2022 3:00:47 PM"
$matches = [regex]::Match($test,"REGISTRATION.+\.csv")
$Matches.Value
$FilePath | Select-String -Pattern 'Name\s(.*?),' -AllMatches| Foreach-Object {$.Matches} | Foreach-Object {$.Groups[1].Value}
I have a below powerShell script that creates homedrive for user,
Import-Module ActiveDirectory 2>&1 | Write-Host;
if($?)
{
$homeDir = "\\CORP.com\HOME\Jdoe";
$user = "jdoe";
$domain = "Corp";
New-Item "$homeDir" -type directory;
$acl = Get-Acl "$homeDir";
$permission = "$domain\$user","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow";
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission;
$acl.SetAccessRule($accessRule);
$acl | Set-Acl "$homeDir";
}
Values within $homeDir and $User will be passed on runtime basis.
How to execute above script along with pass runtime values in $homeDir and $User attribute.
I have tried to execute,
. 'C:\hd.ps1' $homeDir = "\\CORP.com\HOME\test" $user = "test" ; without success.
Can anyone guide, what i am doing incorrect.
Put
param(
$homeDir,
$user
)
At the top of the script and call using
Powershell -File "C:\hd.ps1" -homeDir "\\CORP.com\HOME\test" -user "test"
Why are you doing this?
Import-Module ActiveDirectory 2>&1 | Write-Host;
If you are on the DC doing this or if you have the RSAT tools on your workstation, if you are on PowerShell v3+ or higher, this gets auto loaded the moment you use an AD cmdlet.
Also never user Write-Host for anything that you plan to need later. It empties / clears the buffer. Write-Host is only good for text coloring or other formatting needs in s
Make this a collection from a file for example and just read it in. I'm just using a list here:
$UserFile = #'
Property,Value
homeDir,\\CORP.com\HOME\Jdoe
user,jdoe
Targetdomain,Corp
'# | ConvertFrom-Csv
# Results
Property Value
-------- -----
homeDir \\CORP.com\HOME\Jdoe
user jdoe
Targetdomain Corp
If you are doing this from a remote machine, then you cannot use local varibles in a remote session unless you set its scope.
Get-Help about_remote_variables -Full
About Remote Variables
LONG DESCRIPTION
You can use variables in commands that you run on remote
computers.Simply assign a value to the variable and then use the
variable inplace of the value.
By default, the variables in remote commands are assumed to be
definedin the session in which the command runs. You can also use
variablesthat are defined in the local session, but you must identify
them aslocal variables in the command.
USING LOCAL VARIABLES
You can also use local variables in remote commands, but you
mustindicate that the variable is defined in the local session.
Beginning in Windows PowerShell 3.0, you can use the Using
scopemodifier to identify a local variable in a remote command.
The semi-colons are not needed in PowerShell, unless the items are on the same line.
You cannot call this code this way...
'C:\hd.ps1' $homeDir = "\\CORP.com\HOME\test" $user = "test"
... since you did not specify any params in your code.
So, something like this...
Note: I am not in a position to test this... please do only in a test environment
So this is off the cuff...
ForEach($UserLine in $UserFile)
{
New-Item $UserLine.homeDir -type directory
$acl = Get-Acl $UserLine.homeDir
$permission = ($Using:UserLine.Targetdomain + '\' + $Using:UserLine.user),'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl $Using:UserLine.homeDir
}
If you want this to be a parameterized function, then this.,.
Function New-ADUserHomeDirSettings
{
[cmdletbinding()]
Param
(
[string]$homeDir,
[string]$user,
[string]$Targetdomain
)
$acl = Get-Acl $UserLine.homeDir
$permission = ($Using:UserLine.Targetdomain + '\' + $Using:UserLine.user),'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl $Using:UserLine.homeDir
}
New-ADUserHomeDirSettings -homeDir '' -user '' -Targetdomain ''
Background:
In my work environment, we have a transitional location for our knowledgebase notes. These reside in a number of OneNote 2016 workbooks which have been maintained over years. I am currently in the middle of delegating content update efforts to our staff and part of this work involves importing all our OneNote notebook names and section names into an excel spreadsheet for hierarchy management.
Task: I spent ages looking online for an easy and quick way to export hierarchy information from OneNote to csv using PowerShell and could not for the life of me find an easy way that worked. The following code resonated through the interwebs but each time I tried to run the code, I kept getting errors.
$onenote = New-Object -ComObject OneNote.Application
$scope = [Microsoft.Office.Interop.OneNote.HierarchyScope]::hsPages
[ref]$xml = $null
$onenote.GetHierarchy($null, $scope, $xml)
$schema = #{one=”http://schemas.microsoft.com/office/onenote/2013/onenote”}
$xpath = “//one:Notebook/one:Section”
Select-Xml -Xml (
$xml.Value) -Namespace $schema -XPath $xpath |
foreach {
$node = $psitem.Node
$npath = Split-Path -Path $node.Path -Parent
$props = [ordered]#{
Workbook = Split-Path -Path $npath -Leaf
Section = $node.Name
}
New-Object -TypeName PSObject -Property $props
}
Error:
The error I would get from executing this code was as follows:
value of type "System.String" to type "System.Xml.XmlNode".
At line:10 char:17
+ Select-Xml -Xml (
Solution:
In the end I had to break down the established connection to the Onenote Application and found a workable solution for OneNote 2016. I've provided my solution but am keen to hear of any other possible ways to manipulate this data effectively in the future:
Function Get-OneNoteHeaders{
[CmdletBinding()]
Param()
Begin
{
$onenote = New-Object -ComObject OneNote.Application
$scope = [Microsoft.Office.Interop.OneNote.HierarchyScope]::hsPages
[ref]$xml = $null
$csvOutput = "c:\temp\onenote-headers.csv"
}
Process
{
$onenote.GetHierarchy($null, $scope, $xml)
[xml]$result = ($xml.Value)
Foreach($notebook in $($result.DocumentElement.Notebook)){
Add-content -Path $csvOutput -Value "$($notebook.name)"
Foreach($section in $($notebook.section)){
Add-content -Path $csvOutput -Value ",$($section.name)"
Foreach($page in $section.page){
Add-content -Path $csvOutput -Value ",,$($page.name)"
}
}
}
}
End{}
}
#Get-OneNoteHeaders
I have an array of Credential objects and I would like to test that these credentials have permissions to write a file to a file share.
I was going to do something like
$myPath = "\\path\to\my\share\test.txt"
foreach ($cred in $credentialList)
{
"Testing" | Out-File -FilePath $myPath -Credential $cred
}
but then I discovered that Out-File doesn't take Credential as a parameter. What's the best way to solve this?
You can use New-PSDrive:
$myPath = "\\path\to\my\share"
foreach ($cred in $credentialList)
{
New-PSDrive Test -PSProvider FileSystem -Root $myPath -Credential $Cred
"Testing" | Out-File -FilePath Test:\test.txt
Remove-PSDrive Test
}
Here is asituation where an old exe (net.exe) seems to do better than powershell...
I guess you could try to map a network drive with the credential provided then test to write a file to that drive :
$cred=get-credential
$pass=$cred.GetNetworkCredential().Password
net use q: \\servername\share $pass /user:$cred.username
Use this script taken from Microsofts TechNet Script Center : http://gallery.technet.microsoft.com/scriptcenter/Lists-all-the-shared-5ebb395a
It is a lot easier to alter to fit your needs then to start completely from scratch.
Open up ListSharedFolderPermissions.ps1, and find the three $Properties vars. add a line at the top of each one so you can tell which user your looking at, so it should now look like this:
$Properties = #{'Username' = $Credential.UserName
'ComputerName' = $ComputerName
. . . . . }
Next, add your new Username property to the select-object line (3 times) :
$Objs|Select-Object Username,ComputerName,ConnectionStatus,SharedFolderName,SecurityPrincipal, `
FileSystemRights,AccessControlType
Once youve added those small pieces in the six appropriate places your script is ready to use:
cd c:\Path\where\you\put\ps1\file
$permissions = #()
$myPath = "computername"
foreach ($cred in $credentialList)
{
$permissions += .\ListAllSharedFolderPermission.ps1 -ComputerName $myPath -Credential $cred
$permissions += " "
}
$permissions | Export-Csv -Path "C:\Permission.csv" -NoTypeInformation
Try using the Invoke-Command function. It will take a credential object and allow you to run an arbitrary script block under that command. You can use that to test out writing the file
Invoke-Command -ScriptBlock { "Testing" | Out-File $myPath } -Credential $cred
I think the Invoke-command approach should work. But if nothing works you can try the powershell impersonation module. It successfully impersonates a user for most Powershell commands without the -Credential switch.
A few ideas:
Create your own PowerShell Provider
Impersonate a user and then write to the share (not sure if possible in powershell)
Use net use d:... as #Kayasax has suggested
Use WScript.Network
I'm very interested in the PowerShell provider myself, but I decided to make something real quick so I went with using the WScript.Network library. I used a hash table to track whether a user would be "authenticated" or not.
$credentials = #() # List of System.Net.NetworkCredential objects
$authLog = #{}
$mappedDrive = 'z:'
$tmpFile = $mappedDrive, '\', [guid]::NewGuid(), '.tmp' -join ''
$path = [io.path]::GetPathRoot('\\server\share\path')
$net = new-object -comObject WScript.Network
foreach ($c in $credentials) {
if ($authLog.ContainsKey($c.UserName)) {
# Skipping because we've already tested this user.
continue
}
try {
if (Test-Path $mappedDrive) {
$net.RemoveNetworkDrive($mappedDrive, 1) # 1 to force
}
# Attempt to map drive and write to it
$net.MapNetworkDrive($mappedDrive, $path, $false, $c.UserName, $c.Password)
out-file $tmpFile -inputObject 'test' -force
# Cleanup
Remove-Item $tmpFile -force
$net.RemoveNetworkDrive($mappedDrive, 1)
# Authenticated.
# We shouldn't have reached this if we failed to mount or write
$authLog.Add($c.UserName, 'Authorized')
}
catch [Exception] {
# Unathenticated
$authLog.Add($c.UserName, 'Unauthorized')
}
}
$authLog
# Output
Name Value
---- -----
desktop01\user01 Authorized
desktop01\user02 Unauthorized
I have the powershell script built and I'm getting a "Random" bit of output into the CSV file. The string is MailboxExport(and a number). It looks like a value that (Get-MailboxExportRequest).name would return but I can't see where I would pull something like that or how it is being inserted. I think I may have just been staring at it too long and I may just need a fresh pair of eyes to spot my mistake. I would go into what the script is trying to do but I've put quite a few notes in the script that should explain it fairly well.
################################################## PST Extraction Script ##################################################
# Completed October 2013 by Trey Nuckolls
#
# This script is meant to extract PST files from the Site 1 Exchange server at the Site2 site and deliver those PST
# files to a share on the Site2 network. The script will change the input CSV file to keep track of which PSTfiles have been
# extracted and when that occoured. The script will also set security on the PST file so only the user and IT administraion
# can access the PST file.
#
# To run this script, enter the username of the Site 1 domain account that you want to target for extraction of a PST file then
# Run the script. Can be run from any machine on the network as long as it is run by someone with domain admin rights on the
# Site 2 network. Powershell v2 or v3 is required to run the script.
#
#############################################################################################################################
$InPstPath = '\\Site1_Server\PST_Store'
$OutPstPath = '\\Site2_Server\PST_Store'
$AdminPath = '\\Site2_Server\PST_Store\Admin\'
#Container for Site1 username
$User = Get-Content $AdminPath'login.txt'
#Container for encrypted Site1 Password
$PWord = Cat $AdminPath'pass.txt' | ConvertTo-SecureString
#Credential package for accessing Site1 resouces
$Credentials = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $User, $PWord
#Creation of Powershell Drives for use during session
New-PSDrive -Name Site1Share -PSProvider FileSystem -Root $InPstPath -Credential $Credentials
New-PSDrive -Name Site2Share -PSProvider FileSystem -Root $OutPstPath
#Container for Powershell session to Exchange server
$PSSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://Site1_Server/powershell -Credential $Credentials
#Creation of Powershell session to Site1 Exchange server, including import of exchange commandlets
Import-PSSession $PSSession
#Import of the CSV file that lists users to be targeted
$In_List = Invoke-Command {Import-Csv "\\Site1_Server\PST_Store\To_Be_Exported.csv"} -computername Site1_Server -Credential $Credentials
$Processed = foreach ($objUser in $In_List) {
if ($objUser.Completed -ne "Yes") {
$TargetUser = $objUser.name
$ShortDate = (Get-Date).toshortdatestring()
$SourceFile = "Site1Share:\$TargetUser.pst"
$DestinationFile = "Site2Share:\$TargetUser.pst"
#Export Mailbox to PST File
New-MailboxExportRequest -Mailbox $TargetUser -Filepath $InPstPath\$TargetUser.pst
do {Start-Sleep -Seconds 10}
until((Get-MailboxExportRequest -Status InProgress).count -eq 0)
#Copy PST File to PST Share
Copy-Item -Path $SourceFile -Destination $DestinationFile
#Add Security access on PST file (Target_User-Modify). Domain Admin-Full is inherited from parent.
$Acl = Get-Acl $DestinationFile
$Permission = "Site2_Domain\$TargetUser","Modify","Allow"
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $Permission
$Acl.SetAccessRule($AccessRule)
$Acl | Set-Acl $DestinationFile
#Remove PST file From Temporary area
Remove-Item -Path $SourceFile -Force
#Write back to checklist for new items that have just been processed
[PSCustomObject]#{Name=$TargetUser;Completed="Yes";Date=$ShortDate}
} else { if ($objUser.Completed -eq "Yes") {
#Passthrough of items that have already been completed
[PSCustomObject]#{Name=$objUser.name;Completed=$objUser.Completed;Date=$objUser.Date}}
}}
#Output the new version of the checklist
$Processed | export-csv -Path C:\TEMP\processed.csv
#Overwrite the old version checklist with the new one
Move-Item -Path C:\TEMP\processed.csv -Destination Site1Share:\To_Be_Exported.csv -force
#Cleanup PsDrives and PsSessions
Remove-PSDrive -Name Site1Share
Remove-PSDrive -Name Site2Share
Remove-PSSession -Session (Get-PSSession)
Input CSV is...
"Name","Completed","Date"
"User1","Yes","10/8/2013"
"User2","Yes","10/11/2013"
"User3",,
and output is...
"Name","Completed","Date"
"User1","Yes","10/8/2013"
"User2","Yes","10/11/2013"
"MailboxExport7",,
"User3","Yes","10/11/2013"
It is indeed very likely that the issue is caused by New-MailboxExportRequest, as you already suspected. The cmdlet prints information about the created object, which lumped together with the rest of the output you create in the loop, and then assigned to the variable $Processed.
To avoid this you can suppress the cmdlet output like this:
New-MailboxExportRequest -Mailbox ... | Out-Null
or like this:
New-MailboxExportRequest -Mailbox ... >$null
Assigning the output to a variable should work as well:
$exportRequest = New-MailboxExportRequest -Mailbox ...
On you Export-CSV, try adding the flag: "-NoTypeInformation"
I think this may be some sort of name space crossover issue between the custom object and another existing object (probably the mailboxexportrequest object on the exchange server). After messing around with this for a while I was able to get it to fail in a new way where the resultant csv file was full of details from the mailbox exports and their was a 'name' column that also had listed the usernames. I changed the hashes on the input csv from 'name to 'username' and the resultant MailboxExport entries have ceased. There are now blank row but I'm certainly willing to live with that imperfection as it doesn't break this (short lived) process.
If anyone has any insight into the root cause I'd certainly love to hear what it is but I think I've figured out a solution to the point that I can live with.