I am attempting to pull the various Workspaces and associated user details from Power BI using the Powershell Power BI Management objects. When I make a call to the Get-PowerBIWorkspace in powershell, the user element (and others) is blank
Connect-PowerBIServiceAccount -Credential $credential
$Groups = Get-PowerBIWorkspace
foreach($group in $Groups)
{
$group
}
Disconnect-PowerBIServiceAccount
Exampl output
Id : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Name : test
IsReadOnly : False
IsOnDedicatedCapacity : False
CapacityId :
Description :
Type :
State :
IsOrphaned : False
Users :
Reports :
Dashboards :
Datasets :
Dataflows :
Workbooks :
Has anyone seen this before?
A bit more tinkering and I got the below bit of code to list out the users. Obviously it will need some tidying up.
$workspaces = Get-PowerBIWorkspace -Scope Organization -All | Where {($_.Type -eq "Workspace") -and ($_.State -eq "Active")}
foreach ($workspace in $workspaces)
{
$user = $workspace.Users
$user.Identifier
}
i am trying to modify a permission to multiple computers in my domain so that they are allowed to authenticate cross domain.
My code is simple however i keep getting an error.
Function Add-ADGroupACL
{
param([string]$Computername,[string]$Access)
#Get a reference to the RootDSE of the current domain
$rootdse = Get-ADRootDSE
#Get a reference to the current domain
$domain = Get-ADDomain
#Create a hashtable to store the GUID value of each extended right in the forest
$extendedrightsmap = #{}
Get-ADObject -SearchBase ($rootdse.ConfigurationNamingContext) -LDAPFilter `
"(&(objectclass=controlAccessRight)(rightsguid=*))" -Properties displayName,rightsGuid |
% {$extendedrightsmap[$_.displayName]=[System.GUID]$_.rightsGuid}
#Create a hashtable to store the GUID value of each schema class and attribute
$guidmap = #{}
Get-ADObject -SearchBase ($rootdse.SchemaNamingContext) -LDAPFilter `
"(schemaidguid=*)" -Properties lDAPDisplayName,schemaIDGUID |
% {$guidmap[$_.lDAPDisplayName]=[System.GUID]$_.schemaIDGUID}
#Get the computer object for modification on
$Computer = Get-ADComputer -Identity $Computername
#get the SID of the group you wish to add to the computer.
$GroupIdentity = New-Object System.Security.Principal.SecurityIdentifier(Get-ADGroup -Identity $Access).SID
$computersADPath = "AD:\" + $Computer.DistinguishedName
$ComputerACL = Get-ACL $computersADPath
#Create a new rule to add to the object
$newAccessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$GroupIdentity,"ExtendedRight",
"Allow",
$extendedrightsmap["Allowed To Authenticate"],
"None")
$newAccessRule
#Add the rule to the ACL
$ComputerACL.AddAccessRule($newAccessRule)
#Set Rules to the ACL
Set-Acl -AclObject $ComputerACL -Path $computersADPath
}
I have posted the entire function to make it easy.
Simply call this as so
Add-ADGroupACL -Computername 'TestComputer' -Access 'TestGroup'
end here is the error message that i keep getting
Set-Acl : This security ID may not be assigned as the owner of this object
At line:88 char:5
+ Set-Acl -AclObject $ComputerACL -Path $computersADPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (CN=testComputer,OU=Co...C=subdomain,DC=domain:String) [Set-Acl], ADException
+ FullyQualifiedErrorId : ADProvider:SetSecurityDescriptor:ADError,Microsoft.PowerShell.Commands.SetAclCommand
The Access Rule looks right. it shows this.
ActiveDirectoryRights : ExtendedRight
InheritanceType : None
ObjectType : 68b1d179-0d15-4d4f-ab71-46152e79a7bc
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : S-1-5-21-2926237862-3770063950-2320700579-361721
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Any help would be greatly appreciated.
Thank you.
For anyone else who gets this problem, the here is the solution.
Basically, how Get-ACL and Set-ACL works is that it retrieves the entire ACL. you make edits to the ACL and then Set-ACL attempts to rewrite the entire ACL.
More Info: https://learn.microsoft.com/en-us/windows/desktop/secauthz/access-control-entries
So basically you need to just create an ACE and add it to the ACL on the fly. this can best be done buy utilising DACLS
Code:
Function Add-ADGroupACEExtendedRight
{
param(
[string]$Computername = $(throw "Computer name must be specified"),
[string]$Access = $(throw "User or group in which to give acces must be specifieds"),
[string]$ExtendedRight = $(throw "Extended Right Property Name Required")
)
#Get the computer object for modification on
$Computer = Get-ADComputer -Identity $Computername
#get the SID of the group you wish to add to the computer.
$GroupIdentity = New-Object System.Security.Principal.SecurityIdentifier(Get-ADGroup -Identity $Access).SID
#Set Permissions
dsacls $Computer.DistinguishedName /G $GroupIdentity":CA;"$ExtendedRight
}
Usage:
Add-ADGroupACEExtendedRight -Computername "TestAsset" -Access "GroupID" -ExtendedRight "Allowed To Authenticate"
you can add any extended right here.
more information on DACLS: https://technet.microsoft.com/pt-pt/library/cc787520%28v=ws.10%29.aspx?f=255&MSPPError=-2147217396
I know that this subject was already discussed here but solutions here and on other sites seem not to work for me.
I want to add to CNO: "CLUSTER" permission on OU to Create Computer Object.
More or less all solution are based on following idea:
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
$acl = get-acl $ou
$objectGUID = New-Object guid bf967a86-0de6-11d0-a285-00aa003049e2
$guidNull = New-Object guid 00000000-0000-0000-0000-000000000000
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"ReadProperty,GenericExecute","Allow",$guidNull,"None",$guidNull
$acl.AddAccessRule($ace1)
$ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild","Allow",$ObjectGUID,"None",$guidNull
$acl.AddAccessRule($ace2)
set-acl -aclobject $acl $ou
I am getting following error:
Set-Acl : This security ID may not be assigned as the owner of this object
At line:1 char:8
+ set-acl <<<< -aclobject $acl $ou
+ CategoryInfo : NotSpecified: (OU=sql,OU=ssd...=xxx,DC=net:String) [Set-Acl], ADException
+ FullyQualifiedErrorId : ADProvider:SetSecurityDescriptor:ADError,Microsoft.PowerShell.Commands.SetAclCommand
Any idea what can be wrong?
I've seen this error on file systems when using Get-Acl/Set-Acl. Get-Acl retrieves the entire ACL even though you don't want it. You only want the DACL. Set-Acl then attempts to write the entire ACL which fails because Microsoft. Try changing the Get-Acl call to:
$acl = (get-acl $ou).Access
This should only get you the access rules which you are trying to append to.
EDIT
Apologies for the misinformation, on a filesystem this works but AD is "special". The underlying issue is the same, Get-Acl pulls everything and Set-Acl chokes when it attempts to set the owner. Try running the above command in an powershell window run as admin under a domain administrator's context. This may allow you to force past it. Instead I would try using the ADSI accelerator.
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
$ouObject = [ADSI]("LDAP://$OU")
$objectGUID = New-Object guid bf967a86-0de6-11d0-a285-00aa003049e2
$guidNull = New-Object guid 00000000-0000-0000-0000-000000000000
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"ReadProperty,GenericExecute","Allow",$guidNull,"None",$guidNull
$ouObject.psbase.ObjectSecurity.AddAccessRule($ace1)
$ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild","Allow",$ObjectGUID,"None",$guidNull
$ouObject.psbase.ObjectSecurity.AddAccessRule($ace2)
$ouObject.psbase.CommitChanges()
Another option would be to try working around it with dsacls, you'll need to figure out exactly which permissions syntax you want to use though. Please test before running on a live OU.
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
#should grant the SID Generic Execute, Read Property, Create Children
dsacls $ou /G $sid:GERPCC
seems to be working on any AD object, including DNS records via DN:
dsacls $DistinguishedName /G "NT AUTHORITY\Authenticated Users:GW"
I'm trying to apply NTFS permissions that are defined in the 'Advanced' tab of the Windows security settings. One ACL $Rule is for This folder only and another one is for the Subfolders and files only.
The permissions are heavily modified as you can see below:
(Get-Acl 'L:\Test\Beez\RAPJOUR\Appels List\Correct').Access
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : None
FileSystemRights : CreateFiles, AppendData, DeleteSubdirectoriesAndFiles, ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : DeleteSubdirectoriesAndFiles, Modify, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : InheritOnly
Everything is on except for : Full control, Write attributes, Write extended attributes, Delete, Change permissions and Take ownership.
Everything is on except for : Full control, Change permissions and Take ownership.
This is a piece of the code I use to apply permissions. In this case it has to be defined in the part Change:
$f = 'L:\Test\Beez\RAPJOUR\Appels List\Wrong'
$ADobject = 'Domain\User'
$acl = Get-Acl $f
$Grant = 'Change'
# Remove user/group first
$rule = New-Object system.security.AccessControl.FileSystemAccessRule("$ADobject","Read",,,"Allow")
$acl.RemoveAccessRuleAll($rule)
# Add read permissions
if ($Grant -eq 'ReadAndExecute') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'Change') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "Synchronize", "Allow DeleteSubdirectoriesAndFiles")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "AppendData", "ContainerInherit, ObjectInherit", "ReadAndExecute","Synchronize", "Allow CreateFiles","DeleteSubdirectoriesAndFiles")
}
if ($Grant -eq 'Modify') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'FullControl') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
}
if ($Grant -eq 'ListFolderContents') {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit", "None", "Allow")
}
$acl.AddAccessRule($rule)
Set-Acl $f $acl
I can't seem to get the syntax right.. Thank you for your help.
Thanks to this post I've already found the part for:
'Subfolders and files only': "ContainerInherit, ObjectInherit", "InheritOnly"
'This folder only': "None", "InheritOnly"
Object access permissions in Windows are controlled via Access Control Lists (ACL), which basically consist of a list of Access Control Entries (ACE). Each ACE is a set of attributes that controls whether access is granted or denied, who the ACE applies to, if the ACE was inherited from a parent object, and whether it should be inherited by child objects.
If you take a look at the documentation of the FileSystemAccessRule class, you'll see that the "full" constructor takes 5 parameters:
IdentityReference/String: An object or string that identifies the trustee (user, group, computer, ...) to whom the ACE applies.
FileSystemRights: The actual permissions to be granted or denied.
InheritanceFlags: Flags to control which object types inherit permissions from this object (containers, leaf objects, or none).
PropagationFlags: Flags to control propagation of permissions. The flag InheritOnly exempts the current object from receiving the ACE. The flag NoPropagateInherit restricts inheritance to immediate child objects.
AccessControlType: The type of the ACE (allow or deny).
Now, if you want to assign multiple access rights to a given trustee, you can either do that with individual ACEs:
$acl = Get-Acl $path
$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ListDirectory', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace1)
$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ReadAttributes', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace2)
...
Or by providing the permissions as a comma-separated string:
$acl = Get-Acl $path
$ace = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'ListDirectory, ReadAttributes, ...', 'ContainerInherit, ObjectInherit',
'InheritOnly', 'Allow'
$acl.AddAccessRule($ace)
Note, however, that you cannot grant and deny permissions with the same ACE. If you want to deny specific access rights you need to do it with a separate ACE:
$acl = Get-Acl $path
$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'Modify', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Allow'
$acl.AddAccessRule($ace1)
$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',
'CreateDirectories', 'ContainerInherit, ObjectInherit', 'InheritOnly',
'Deny'
$acl.AddAccessRule($ace2)
...
Note also, that explicit permissions take precedence over inherited permissions, and Deny takes precedence over Allow.
You know how it goes when you're fighting world problems. The moment you post the question, you find the answer 5 minutes later...
Thanks to the answer of Frode F. on another question, I found the solution to my own problem. I had to copy the output of the line FileSystemRights in $Correct.Access and paste it in an Array as you can see below:
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", #("CreateFiles", "AppendData", "DeleteSubdirectoriesAndFiles"," ReadAndExecute", "Synchronize"), "None", "InheritOnly", "Allow") # This folder only
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", #("DeleteSubdirectoriesAndFiles", "Modify", "Synchronize"), "ContainerInherit, ObjectInherit", "InheritOnly", "Allow") # Subfolders and files only
I have a user's network login name. From PowerShell and WMI is it possible to get a valid email for that user? Note that the login name is different than the name in the email, so I can't just combine the login name with the email domain.
The simplest way is to useActive-Directory.
As you are using PowerShell tag and not PowerShell V2.0 you can use ADSI.
Clear-Host
$dn = New-Object System.DirectoryServices.DirectoryEntry ("LDAP://WM2008R2ENT:389/dc=dom,dc=fr","jpb#dom.fr","Pwd")
# Look for a user
$user2Find = "user1"
$Rech = new-object System.DirectoryServices.DirectorySearcher($dn)
$rc = $Rech.filter = "((sAMAccountName=$user2Find))"
$rc = $Rech.SearchScope = "subtree"
$rc = $Rech.PropertiesToLoad.Add("mail");
$theUser = $Rech.FindOne()
if ($theUser -ne $null)
{
Write-Host $theUser.Properties["mail"]
}
You can also use userPrincipalName instead of sAMAccountName in the filter, for userPrincipalName you can use user#domain form.
Using WMI : If you absolutly want to do it with WMI.
$user2Find = "user1"
$query = "SELECT * FROM ds_user where ds_sAMAccountName='$user2find'"
$user = Get-WmiObject -Query $query -Namespace "root\Directory\LDAP"
$user.DS_mail
You can use the second solution localy on your server or from a computer inside the domain, but it's a bit more complicated to authenticate to WMI from outside the domain.
Using PowerShell 2.0
Import-Module activedirectory
$user2Find = "user1"
$user = Get-ADUser $user2Find -Properties mail
$user.mail
Here's another possible way (original source):
PS> [adsisearcher].FullName
System.DirectoryServices.DirectorySearcher
PS> $searcher = [adsisearcher]"(objectClass=user)"
PS> $searcher
CacheResults : True
ClientTimeout : -00:00:01
PropertyNamesOnly : False
Filter : (objectClass=user)
PageSize : 0
PropertiesToLoad : {}
ReferralChasing : External
SearchScope : Subtree
ServerPageTimeLimit : -00:00:01
ServerTimeLimit : -00:00:01
SizeLimit : 0
SearchRoot :
Sort : System.DirectoryServices.SortOption
Asynchronous : False
Tombstone : False
AttributeScopeQuery :
DerefAlias : Never
SecurityMasks : None
ExtendedDN : None
DirectorySynchronization :
VirtualListView :
Site :
Container :
PS> $searcher = [adsisearcher]"(samaccountname=$env:USERNAME)"
PS> $searcher.FindOne().Properties.mail
Not WMI, but this may do the job just as well:
PS> ([adsi]"WinNT://$env:USERDOMAIN/$env:USERNAME,user").Properties["mail"]