Create Libraries and Permissions with SharePoint Powershell - powershell

I'm trying to make a script to help automate this process a bit but am fairly new to using PowerShell with SharePoint and don't really know the route to take.
I have a list of 40 items and I need to make a library for each one. Each library then needs to have unique permissions with 3 default groups(Owners, Members, Visitors). The groups should be named the same as the List.Title + Owners/Members/Visitors.
So far I create a site group as follows:
# Owner Group
$web.SiteGroups.Add(“$web Owners”, $web.Site.Owner, $web.Site.Owner, “Use this group to grant people full control permissions to the $web site”)
$ownerGroup = $web.SiteGroups["$web Owners"]
$ownerGroup.AllowMembersEditMembership = $true
$ownerGroup.Update()
The naming of my groups needs to be the list title and not the web name as I have above.
I create a new library like this:
PS > $spWeb = Get-SPWeb -Identity http://SPServer
PS > $listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
PS > $spWeb.Lists.Add("My Documents","My Doc Library",$listTemplate)
Clearly this is not automated at all and no faster than just using the GUI to make each new library and adding in the site groups. Can anyone help get me started on a script that would iterate through a list of names create a library and create 3 groups on the site for each new library?
Thanks!!

This should get you on the right track I believe.
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
$Lists = #("My Documents", "My Docs", "Testing")
$Groups = #("Owners", "Members", "Visitors")
$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary
$Web = Get-SPWeb "Your_URL"
$Lists | ForEach-Object {
$ListName = $_
$Description = "$_ Description"
$Web.Lists.Add($ListName, $Description, $listTemplate)
$Groups | % {
$GroupName = "$ListName $_"
$Web.SiteGroups.Add($GroupName, $Web.Site.Owner, $Web.Site.Owner, "Group $GroupName created by automatic process")
$group = $Web.SiteGroups["$GroupName"]
if ( !$GroupName -contains "Visitors")
{
$group.AllowMembersEditMembership = $true
} else
{
$group.AllowMembersEditMembership = $false
}
$group.Update()
}
}

Related

Add user in domain1 to domain2 group with powershell?

I am looking for some powershell code that can add a user from one domain to another domain group. I can't seem to find the magic code that will work that uses System.DirectoryServices.
###############
# Query user
################
# Variables
$path="GC://ldap-server.company.com"
# To limit the information returned add properties. Use an empty string to
pull everything
$property="objectcategory,distinguishedname,cn,mailnickname,samaccountname"
$searchFilter="(&(objectClass=User)(samaccountname=joker))"
$rootEntry = New-Object System.DirectoryServices.DirectoryEntry $path
$search= New-Object System.DirectoryServices.DirectorySearcher $rootEntry;
if ($properties) {
foreach ($property in [regex]::split($properties, ", ?")) {
[void]$search.PropertiesToLoad.Add($property);
}
}
$search.Filter = $searchFilter;
$searchResults = $search.FindOne();
$user = $searchResults.GetDirectoryEntry()
$user_dn = $searchResults.GetDirectoryEntry().distinguishedName;
# to find the first or only result, use $searchResults = $search.FindOne();
################
#Query group
################
# Same as Query user, just change
$property="";
$searchFilter="(&(objectClass=Group)(samaccountname=mygroup))";
$search.Filter = $searchFilter;
$searchResults = $search.FindOne();
################
#Add user to group
################
# From your group query
$group_dn = $searchResults.GetDirectoryEntry().distinguishedName
I tried this, but it did not seem to add the user and is ADSI:
$Group = [ADSI]"LDAP://"+$group_dn
$User = [ADSI]"LDAP://"+$user_dn
If ($Group.IsMember($User.ADsPath) -eq $False)
{
$Group.Add($User.ADsPath)
}
I was unfortunate enough to have to do this the hard way once (a domain migration where the source domain was still on Windows Server 2008). What you need to do is add the user or group from the remote domain as a foreign security principal:
...
$group_dn = $searchResults.GetDirectoryEntry().distinguishedName
$fsp = New-Object Security.Principal.NTAccount('DOM1', 'username')
$sid = $fsp.Translate([Security.Principal.SecurityIdentifier]).Value
$group = New-Object DirectoryServices.DirectoryEntry("LDAP://$group_dn")
[void]$group.Member.Add("<SID=$sid>")
$group.CommitChanges()
$group.Close()
If possible you should use the ActiveDirectory module (requires at least Windows Server 2008 R2 and access to the AD Web Services).

Getting generic "Collection Not loaded" error on CSOM powershell when attempting to add group to library permissions

I am attempting to add a group to library permissions. My code is below:
#earlier in my code the list is created so it's already stored at this point, Breaking Inheritance is successful
$myList.BreakRoleInheritance($false,$true)
$myList.Update()
$Ctx.ExecuteQuery()
$GroupnameMembers="Site Members" 
$roleDefs = $Ctx.Web.RoleDefinitions
$webgroups = $Ctx.Web.SiteGroups
$Ctx.Load($roleDefs)
$Ctx.Load($webgroups)
$Ctx.ExecuteQuery()
$roleTypeContributor = [Microsoft.SharePoint.Client.RoleType]"Contributor"
$roleDefContributor = $roleDefs | where {$_.RoleTypeKind -eq $RoleTypeContributor}
$MembersGroup = $webgroups | Where{$_.Title -eq $GroupnameMembers}
$ContributorRoleDefBinding = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($Ctx)
$ContributorRoleDefBinding.Add($roleDefContributor)
#earlier in my code the list is created so it's already stored at this point
$collRoleAssign = $myList.RoleAssignments
$Ctx.Load($collRoleAssign)
$Ctx.ExecuteQuery()
#Crashing on this line below:
$collRoleAssign.Add($MembersGroup, $ContributorRoleDefBinding)
I've tried everything I can think of, I have even manually stepped through the code and I still can't find the issue, I have thrown in Debugging outputs at each stage and confirmed their are values in all 3 variables being used in that final code piece.
Any help/suggestions would be greatly appreciated.
There are a couple of things that I do slightly differently to your script. I get reference to the role definition from the $web:
$roleDefContributor = $web.RoleDefinitions.GetByName("Contribute")
And surround the role assignment in a $ctx.Load(..):
$ctx.Load($collRoleAssign.Add($MembersGroup, $ContributorRoleDefBinding))
Working example:
$list = $web.Lists.GetByTitle($listName)
$ctx.Load($list)
# break inheritance
$list.BreakRoleInheritance($false, $true)
$groupName = "Site Members"
$webgroups = $ctx.Web.SiteGroups
$ctx.Load($webGroups)
$ctx.ExecuteQuery()
$roleDef = $web.RoleDefinitions.GetByName("Contribute")
$group = $webGroups | Where{ $_.Title -eq $groupName }
$roleDefBinding = new-object Microsoft.SharePoint.Client.RoleDefinitionBindingCollection($ctx)
$roleDefBinding.Add($roleDef)
$ctx.Load($list.RoleAssignments.Add($group, $roleDefBinding))
$list.Update()
$ctx.ExecuteQuery()

Missing AD module and can't get it, need something similar or something to simulate it

So I'm trying to output a complete KB list for all computers on a server (which works on one computer) but it doesn't recognize Get-ADcomputer as a cmdlet. When checking various sources, it appears that the AD module isn't included. As I'm doing this on a work computer/server I'm hesitant to download anything or anything of that nature.
Is there any way I can achieve the following without using the AD module or someway I might be missing how to import the module (if it exists, which I don't think it does on this system)?
# 1. Define credentials
$cred = Get-Credential
# 2. Define a scriptblock
$sb = {
$Session = New-Object -ComObject Microsoft.Update.Session
$Searcher = $Session.CreateUpdateSearcher()
$HistoryCount = $Searcher.GetTotalHistoryCount()
$Searcher.QueryHistory(0,$HistoryCount) | ForEach-Object -Process {
$Title = $null
if ($_.Title -match "\(KB\d{6,7}\)") {
# Split returns an array of strings
$Title = ($_.Title -split '.*\((?<KB>KB\d{6,7})\)')[1]
} else {
$Title = $_.Title
}
$Result = $null
switch ($_.ResultCode) {
0 { $Result = 'NotStarted'}
1 { $Result = 'InProgress' }
2 { $Result = 'Succeeded' }
3 { $Result = 'SucceededWithErrors' }
4 { $Result = 'Failed' }
5 { $Result = 'Aborted' }
default { $Result = $_ }
}
New-Object -TypeName PSObject -Property #{
InstalledOn = Get-Date -Date $_.Date;
Title = $Title;
Name = $_.Title;
Status = $Result
}
} | Sort-Object -Descending:$false -Property InstalledOn | Where {
$_.Title -notmatch "^Definition\sUpdate"
}
}
#Get all servers in your AD (if less than 10000)
Get-ADComputer -ResultPageSize 10000 -SearchScope Subtree -Filter {
(OperatingSystem -like "Windows*Server*")
} | ForEach-Object {
# Get the computername from the AD object
$computer = $_.Name
# Create a hash table for splatting
$HT = #{
ComputerName = $computer ;
ScriptBlock = $sb ;
Credential = $cred;
ErrorAction = "Stop";
}
# Execute the code on remote computers
try {
Invoke-Command #HT
} catch {
Write-Warning -Message "Failed to execute on $computer because $($_.Exception.Message)"
}
} | Format-Table PSComputerName,Title,Status,InstalledOn,Name -AutoSize
You've got 3 options:
First is to just install the RSAT feature for AD which will include the AD module. This is probably the best option unless there is something specific preventing it. If you're running your script from a client operating systems you need to install the RSAT first, though.
Option 2 (which should only be used if adding the Windows feature is somehow an issue) is to download and use the Quest AD tools, which give very similar functionality, but it looks like Dell is doing their best to hide these now so that may be difficult to locate...
Option 3 is to use the .NET ADSI classes to access AD directly, which will work without any additional downloads on any system capable of running PowerShell. If you'd like to go this route you should check out the documentation for the interface Here and for the System.DirectoryServices namespace Here.
Edit
Just noticed the last part of your question, what do you mean by "a complete KB list"? Not just Windows updates or things updated manually or whatever? What else would be in a list of Windows updates that was not a Windows update?
You have not mentioned the OSes you are using but in general if you have a server 2008 R2 or above, all you have to do it activate the RSAT feature AD PowerShell Module and you will have the cmdlet you are looking for.
On a client machine, you 'have to' install RSAT, and then activate the features. You can take a look at the technet article for more info: https://technet.microsoft.com/en-us/library/ee449483(v=ws.10).aspx
If you don't want to use that option, then you will have to use .NET ADSI classes. There are tons of examples on how to do this, it basically boils down to a couple of lines really. Technet has examples on this as well: https://technet.microsoft.com/en-us/library/ff730967.aspx

Powershell list group membership of user (Novell eDirectory) NDS LDAP

Trying to figure out, how to map a network share based on group membership of Novell eDir.
I found a smart script in Technet for ActiveDirectory via ADSISEARCHER which is working pretty well in AD :)
# extract group names and removes unnecessary characters
$memberOf = ([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().$does.memberof -replace '^CN=([^,]+).+$','$1'
# check if user is member of group A
if($memberOf -contains "GroupA") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharename')
}
Is there any chance to use something similar for NDS?
As far as I researched I have to use LDAP to connect to NDS and list all groups of a user object, but haven't much luck yet.
Thx
I found a useful script out there which I just have to edit a littlebit...
URL to Script:
http://activedirectoryfaq.com/2014/01/searching-novell-nds-edirectory-with-powershell/
My final script in case somebody needs this crap:
<#
.SYNOPSIS
Mapping a network share based on a specific group membership in NDS
.DESCRIPTION
The script is mapping a network drive, based on a NDS group membership.
The first match wins!
#>
# --------<SET CORRESPONDING VALUES HERE >--------
# Hostname of eDir Server (e.g.: NDSSRV01):
$LDAPServer = "hostname"
# Name of BaseDN (e.g.: o=MyCompany):
$dn = "o=basedn"
# ------------------------------------------------
# set username of current logged on user
$filter = "(uid=$env:USERNAME)"
# Creating necessary objects
[reflection.assembly]::LoadWithPartialName("system.directoryservices.protocols") | out-null
$ldapIdentifier = new-object directoryservices.protocols.ldapdirectoryidentifier($LDAPServer)
$ldapConnection = new-object directoryservices.protocols.ldapconnection($ldapIdentifier,$null,0)
# Attributes to search for:
# To search for multiple use comma separated list (eg: "groupmembership","cn","emailAddress")
[string[]]$attr = "groupmembership"
# Establishing LDAP connection
$scope = $ADS_SCOPE_SUBTREE
$searchRequest = new-object directoryservices.protocols.searchrequest($dn,$filter,$ADS_SCOPE_SUBTREE,$attr)
$searchRequest.typesonly = $false
$searchRequest.sizelimit = 10
$result = [directoryservices.protocols.searchresponse]$ldapConnection.sendrequest($searchRequest)
$entry = $result.entries
# extract group names and removes unnecessary characters
$membership = $entry[0].Attributes["groupmembership"].getValues([string]) -replace '^CN=([^,]+).+$','$1'
# check if user is member of group A
if($membership -contains "GroupA") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharegroupa')
}
# check if user is member of group B
elseif($membership -contains "GroupB") {
# map network-drive
(New-Object -ComObject WScript.Network).MapNetworkDrive('X:','\\filer\sharegroupb')
}
# elseif() ... and so on
# if nothing matches, then:
else {
Write-Host 'current user is not a member of a specified group'
}

Need help in powershell script.

I have sharepoint 2010 toplevel site with name Test. Under test there are three subsites with name test1, test2, test3 respectively. In top level site (Test) there are three custom group names are: test1group, test2group and test3group.
Using powershell script I want to export the group and permission to their respective subsite. For example if we want to export the group and permission in test1 subsite
then only test1group should be inherited not test2group and test3group..and the similary while performing group export for test2 subsite then, only test2group should be inheriated...not test1group and test2group....and so on(for test3 subsite)..
Using the below scripts I was trying to perform this:
function AddGroupToSite($url, $groupName, $permLevel)
{
$web = Get-SPWeb $url
#Break permissions inheritance and copy the groups from parent site into this site (recommended)
$web.BreakRoleInheritance($true)
$web.Update()
#Creating a new group:
$web.SiteGroups.Add($groupName, $web.Site.Owner, $web.Site.Owner, "New Group from powershell 4")
$newGroup = $web.SiteGroups[$groupName]
#Create role assignment:
$newGroupAssign = New-Object Microsoft.SharePoint.SPRoleAssignment($newGroup)
#Assign a specific role
#The possible enumeration values are: None, Guest, Reader, Contributor, WebDesigner, Administrator
$newGroupAssign.RoleDefinitionBindings.Add($web.RoleDefinitions.GetByType($permLevel))
$web.RoleAssignments.Add($newGroupAssign)
#Update web
$web.Update()
$web.Dispose()
}
But everytime its inhereting all the group from top level site(which is default behavior)....Can we customize the powershell script so that we can achieve the above functionality..Any help is highly appreciated.
When you break the inheritance, it creates a copy of what was originally inherited.
I don't have the Sharepoint commands handy, but you should be able to do something like
function Remove-SPGroup ($url, $groupName)
{
$web = Get-SPWeb $url
$web.SiteGroups.Remove($GroupName)
$web.Update()
$web.dispose()
}
to remove the initially inherited groups.
So you could add this to your existing script and have something like
function AddGroupToSite($url, $groupName, $permLevel)
{
$web = Get-SPWeb $url
#Break permissions inheritance and copy the groups from parent site into this site (recommended)
$web.BreakRoleInheritance($true)
$web.Update()
#Creating a new group:
$web.SiteGroups.Add($groupName, $web.Site.Owner, $web.Site.Owner, "New Group from powershell 4")
$newGroup = $web.SiteGroups[$groupName]
foreach ($ExistingGroup in $web.SiteGroups)
{
if ($ExistingGroup.name -notlike $groupname)
{
$web.SiteGroups.Remove($ExistingGroup.name)
}
}
#Create role assignment:
$newGroupAssign = New-Object Microsoft.SharePoint.SPRoleAssignment($newGroup)
#Assign a specific role
#The possible enumeration values are: None, Guest, Reader, Contributor, WebDesigner, Administrator
$newGroupAssign.RoleDefinitionBindings.Add($web.RoleDefinitions.GetByType($permLevel))
$web.RoleAssignments.Add($newGroupAssign)
#Update web
$web.Update()
$web.Dispose()
}