Creating "mysite" through powershell throws error - sharepoint

I'm trying to create a "mysite" though powershell but I run into an error that I have a really hard time find the answer.
This is the error i get:
New-Object : Exception calling ".ctor" with "1" argument(s): "UserProfileApplicationNotAvailableException_Logging :: UserProfileApplicationProxy.ApplicationProperties ProfilePropertyCache does not have c05da7c0-d405-4655-a7fa-08e271f4174d"
This is my PS Code:
param
(
[Parameter(Mandatory=$true)]
[string]$username
)
asnp *sh*
$mysite = Get-SPSite "http://mysite.dev.loc"
$context = Get-SPServiceContext $mysite
$upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
#Create user profile
$profile = $upm.ResolveProfile($username)
if(!$profile)
{
Write-Host "$profile does not have a profile. Can't create personal site"
}
elseif($profile)
{
if($profile.PersonalSite -eq $Null)
{
$profile.CreatePersonalSite()
Write-Host "Personal site created"
}
else
{
Write-Warning "$username already has a personal site"
}
}

looking at this https://social.technet.microsoft.com/Forums/office/en-US/d8ee4f32-c380-4d1d-9f26-59765aae4a7f/getting-errors-when-i-try-to-create-newobject-for-userprofile-manager-powershell-sharepoint-2010?forum=sharepointadminprevious
it looks like a permissions issue. try running it as administrator and running the program itself with admin powers.

Related

Error: Cannot find an overload for "restore" and the argument count: "1"

I am getting this error from the following code. It's coming from $Context.Load($RecycleBinItems). Any idea what's wrong with the code? I am attempting to restore all recyclebin items.
Add-Type -Path "C:\Program Files\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline\3.17.2001.2\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline\3.17.2001.2\Microsoft.SharePoint.Client.Runtime.dll"
Import-Module 'Microsoft.PowerShell.Security'
#Get the Site Owners Credentials to connect the SharePoint
$SiteUrl = "https://phaselinknet.sharepoint.com"
$UserName = Read-host "Enter the Email ID"
$Password = Read-host - assecurestring "Enter Password for $AdminUserName"
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $Password)
# Once Connected, get the Site information using current Context objects
Try {
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Context.Credentials = $Credentials
$Site = $Context.Site
$RecycleBinItems = $Site.RecycleBin
$Context.Load($Site)
$Context.Load($RecycleBinItems)
$Context.ExecuteQuery()
Write-Host "Total Number of Files found in Recycle Bin:" $RecycleBinItems.Count
}
catch {
write - host "Error: $($_.Exception.Message)" - foregroundcolor Red
}
# using for loop to restore the item one by one
Try {
if($RecycleBinItems)
{
foreach($Item in $RecycleBinItems)
{
$Site.RecycleBin.restore($Item.ID)
#Write-Host "Item restored:"$Item.Title
}
}
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
The error message is giving you you answer. There is not a version of the method Restore that takes 1 parameter.
You need to load up a list of items simular to this
$Item = $RecycleBin | Where{$_.Title -eq $ItemName}
Then call restore for the items.
if($Item -ne $null)
{
$Item.Restore()
}
Thanks for the tip. So I load up the first 10 items in the recyclebin, and Write-Host does write out the correct files, but the $Item.Restore() does noting as the files are still not restored:
$itemsToRestore = #()
for ($i = 0; $i -lt 10; $i++)
{
$Item = $RecycleBinItems[$i]
$itemsToRestore += $Item
}
Write-Host "Total Number of Files to Restore:" $itemsToRestore.Count
foreach($item in $itemsToRestore)
{
Write-Host "Item:" $Item.Title
$item.Restore()
}
I found the problem. I missed $Context.ExecuteQuery() after $Item.Restore(). It works now.

Get-ADUser can't find all users

I'm reading in a list of users from a Excel spreadsheet one row at a time. Once I get that I'm attempting to get the user object in Active Directory that matches the username I pulled from the Excel file. Unfortunately, it gets the first user but then every user after that it says that it can't find them. Here's what I'm doing:
do
{
# Get the user's login name
$userPrincipalName = $objWorksheet.Cells.Item($intRow, 1).Value()
# Get the user description
$description = $objWorksheet.Cells.Item($intRow, 2).Value()
$intRow++
$user = Get-ADUser -Filter "userPrincipalName -eq '$userPrincipalName'" -Properties Description
if ($user)
{
if (!($user.Description))
{
$user | Set-ADUser -Description $description
Write-Host "User" $userPrincipalName "was altered."
$num_of_users_altered++
}
else
{
Write-Host "User" $userPrincipalName "already has a description."
}
}
else
{
Write-Host "User" $userPrincipalName "was not found."
$num_of_users_not_altered++
}
}
while ($objWorksheet.Cells.Item($intRow, 1).Value() -ne $null)
Now the first user (the one that is found) is in a different OU from the others. I've tried removing that user from the spreadsheet to see if the issue with them being in different OU's but it just didn't find any of them. Any ideas what I might be doing wrong?
Your loop looks like it should work.
Are you sure that you have UPNs (user1#mydomain.com) for all users, and not samAccountName (user1)?
Do you get any results if you manually run Get-ADUser -Filter "userPrincipalName -eq '$userPrincipalName'" -Properties Description (replace $userPrincipalName with one of the values you get in a "not found"-message?
What happends if you use this ($userPrincipalName = $objWorksheet.Cells.Item($intRow, 1).Value().Trim())?
Does it make a difference if convert your file to CSV? Personally, I would always recommend using a CSV-file with PowerShell. CSV-files are alot easier to work with.
sample:
Import-CSV -Path "c:\mycsvfile.csv" | ForEach-Object {
#Modify to match your column names
$upn = $_.userPrincipalName.Trim()
$desc = $_.description.Trim()
$user = Get-ADUser -Filter "userPrincipalName -eq '$upn'" -Properties Description
if ($user)
{
if (!($user.Description))
{
$user | Set-ADUser -Description $desc
Write-Host "User" $upn "was altered."
$num_of_users_altered++
}
else
{
Write-Host "User" $upn "already has a description."
}
}
else
{
Write-Host "User" $upn "was not found."
$num_of_users_not_altered++
}
}

PowerShell - Loop through all SharePoint Website & continue when an error occurred

$ErrorActionPreference = "Continue"
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction "SilentlyContinue"
$webApp = "Https://SharePointSite.com"
$wa = Get-SPWebApplication -identity $webApp
foreach ($site in $wa.Sites) {
foreach ($web in $site.AllWebs) {
$siteURL = $web.Url
Write-Host $siteURL
}
}
The problem is that when it hits the statement foreach ($site in $wa.Sites), and it cannot get the site due to access denied or any error, it would stop. I would like to continue. I tried to TRY CATCH FINALLY, and it still stops when it encounters an error.
I tried to put in -ErrorAction Continue, but it gives me an error message as
you must provide a value expression on the right-hand side of the '-' operator
How do I get around it so it would continue to the site?
I really appreciate your help.
Thanks
If you want to use try..catch, then you must throw terminating errors. Non-terminating errors are not handles by a try..catch block.
try {
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction Stop;
$webApp = "Https://SharePointSite.com"
$wa = Get-SPWebApplication -identity $webApp -ErrorAction Stop;
foreach ($site in $wa.Sites) {
foreach ($web in $site.AllWebs) {
$siteURL = $web.Url
Write-Host $siteURL
}
}
}
catch {
Write-Host -Object ('Error occurred: {0}' -f $_);
}

How to rename application pool that already has application assigned to it?

I have an Application pool that has a lot of applications been assigned to it, it won't let me rename.
Beside delete and creating a new application pool, is there anyway to get a new name for my application pool? I don't want to go and reassign every application in it.
Assign applications to another pool, rename the one you wanted renamed. Re-assign applications back to your pool.
IIS doesn't support other options
This was the simplest way that I could work it out, although I can't believe this isn't easier.
Import-Module WebAdministration
$oldName = "OldAppPool";
$newName = "NewAppPool";
if(-not (Test-Path IIS:\AppPools\TempPool)){
New-WebAppPool TempPool
}
$tempAppPool = Get-Item IIS:\AppPools\TempPool
foreach($site in Get-ChildItem IIS:\Sites){
$apps = $site | Get-ChildItem | Where-Object { $_.ApplicationPool -eq $oldName }
foreach($app in $apps){
$path = ("IIS:\Sites\{0}\{1}" -f $site.name, $app.name)
$path
Set-ItemProperty $path applicationPool TempPool
}
}
Set-ItemProperty "IIS:\AppPools\$oldName" -Name name -Value $newName
foreach($site in Get-ChildItem IIS:\Sites){
$apps = $site | Get-ChildItem | Where-Object { $_.ApplicationPool -eq "TempPool" }
foreach($app in $apps){
$path = ("IIS:\Sites\{0}\{1}" -f $site.name, $app.name)
$path
Set-ItemProperty $path applicationPool $newName
}
}
Remove-WebAppPool TempPool
No, there isn't.
Either put up with the name, or create a new App Pool and assign the applications one-by-one.
If you need to repeat it on multiple servers, you can even automate it with ADSI and JavaScript or VBScript:
http://msdn.microsoft.com/en-us/library/ms525389(v=vs.90).aspx
I've created similar script to automate this job.
It is a bit different from the other answer here:
It works for WebSites in addition to WebApplications;
It works for all pools: with and without assigned applications;
Powershell script:
Import-Module WebAdministration
Function Rename-AppPool([String]$oldName="", [String]$newName="") {
if ($oldName -eq "") {
Write-Warning "Parameter 'oldName' was not provided."
return
}
if ($newName -eq "") {
Write-Warning "Parameter 'newName' was not provided."
return
}
if(-not (Test-Path "IIS:\AppPools\$oldName")){
Write-Warning "There is no pool with name '$oldName' to rename. Operation stopped."
return
}
if(Test-Path "IIS:\AppPools\$newName"){
Write-Warning "Pool with name '$newName' already exists. Operation stopped."
return
}
Write-Output "Renaming app pool '$oldName' to '$newName'"
$pathsOfPools = New-Object System.Collections.ArrayList
$listOfSites = Get-ChildItem "IIS:\Sites"
foreach ($site in $listOfSites) {
if ($site.applicationPool -eq $oldName) {
$path = ("IIS:\Sites\{0}" -f $site.name)
$pathsOfPools.Add($path) | Out-Null
}
$apps = $site | Get-ChildItem
foreach ($app in $apps) {
if ($app.applicationPool -eq $oldName) {
$path = ("IIS:\Sites\{0}\{1}" -f $site.name, $app.name)
$pathsOfPools.Add($path) | Out-Null
}
}
}
$tempGuid = [Guid]::NewGuid()
$tempName = $tempGuid.Guid
if ($pathsOfPools.Count -gt 0) {
$pathsOfPools
New-WebAppPool $tempName | Out-Null
Write-Output "Temp app pool '$tempName' has been created"
Write-Output "Changing apps to Temp pool"
foreach ($path in $pathsOfPools) {
Set-ItemProperty $path applicationPool $tempName
}
}
Set-ItemProperty "IIS:\AppPools\$oldName" -Name name -Value $newName
Write-Output "Application pool name has been changed"
if ($pathsOfPools.Count -gt 0) {
Write-Output "Changing apps to New pool"
foreach ($path in $pathsOfPools) {
Set-ItemProperty $path applicationPool $newName
}
Remove-WebAppPool $tempName
Write-Output "Temp pool has been removed"
}
}
Rename-AppPool "OldName" "NewBetterName"
Yes, there is an option. Create a dummy app pool or make use of DefaultApppool. Associate the existing site to the defaultapppool . Now go to the original app pool, Stop the app pool and rename.
Associate back the url to the renamed appool.

Validating PowerShell PSCredential

Let's say I have a PSCrendential object in PowerShell that I created using Get-Credential.
How can I validate the input against Active Directory ?
By now I found this way, but I feel it's a bit ugly :
[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
function Validate-Credentials([System.Management.Automation.PSCredential]$credentials)
{
$pctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, "domain")
$nc = $credentials.GetNetworkCredential()
return $pctx.ValidateCredentials($nc.UserName, $nc.Password)
}
$credentials = Get-Credential
Validate-Credentials $credentials
[Edit, two years later] For future readers, please note that Test-Credential or Test-PSCredential are better names, because Validate is not a valid powershell verb (see Get-Verb)
I believe using System.DirectoryServices.AccountManagement is the less ugly way:
This is using ADSI (more ugly?):
$cred = Get-Credential #Read credentials
$username = $cred.username
$password = $cred.GetNetworkCredential().password
# Get current domain using logged-on user's credentials
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password)
if ($domain.name -eq $null)
{
write-host "Authentication failed - please verify your username and password."
exit #terminate the script.
}
else
{
write-host "Successfully authenticated with domain $domain.name"
}
I was having a similar issue with an installer and required to verify the service account details supplied. I wanted to avoid using the AD module in Powershell as I wasn't 100% this would be installed on the machine running the script.
I did the test using the below, it is slightly dirty but it does work.
try{
start-process -Credential $c -FilePath ping -WindowStyle Hidden
} catch {
write-error $_.Exception.Message
break
}

Resources