Custom SPJobDefinition and “Access denied” Error
I found Stef Van Hooijdonk’s post when trying to install a custom timer job and having the “Access denied” -issue. I tried Stef’s workaround by running the powershell -script he provided and got my custom timer job to install via web scoped feature’s feature receiver.
I think there are issues to consider though. Do we want to permanently set the RemoteAdministratorAccessDenied false or do we want to run one script to set RemoteAdministratorAccessDenied false before feature activation/deactivation and after that run another script to set it back true again? Installing custom timer job evidently is an operation where Farm Admin privileges are needed and if the activator is web- or site-scoped feature, the activation dialog (the Activate/Deactivate-buttons in ManageFeatures.aspx) is available also for users with inadequate privileges. After further investigation it seems that to activate a feature from content application’s feature management UI, it is necessary to have the same application pool accounts for the content application and central admin – it seems not to be enough to be logged on to your content web app with farm admin account or with the central admin’s application pool account. The behavior is a little weird but at least when I tested different scenarios, this is how it appears to be. To have same application pool account in Central Admin and content web app, however, is not recommended.
Nevertheless, I needed a custom timer job to be installed from a web scoped feature because the timer job handles information per web. Therefore the name of the installed timer job is per web and properties to determine which web should be handled when timer job ticks are also added to the timer job’s properties.
So, I took the idea from Stef’s post and used the same idea in my feature receiver and by doing so I don’t have to run the powershell-script per environment before feature activation:
{
private const string MyCustomTimerJobName =
"Custom Timer Job for web: {0}";
public override void FeatureActivated(SPFeatureReceiverProperties
properties)
{
using (var web = properties.Feature.Parent as SPWeb)
{
if (web == null) return;
// THE ORIGINAL VALUE OF REMOTE ADMINISTRATOR
var remoteAdministratorAccessDenied =
SPWebService.ContentService.
RemoteAdministratorAccessDenied;
try
{
// SET THE REMOTE ADMINISTATOR ACCESS DENIED FALSE
SPWebService.ContentService.
RemoteAdministratorAccessDenied = false;
// delete the custom timer job if it exists
var app = web.Site.WebApplication;
foreach (var job in
app.JobDefinitions.Where(job =>
job.Name == string.Format(MyCustomTimerJobName,
web.Url)))
{
job.Delete();
}
// install the custom timer job
var schedule = new SPMinuteSchedule
{
BeginSecond = 0,
EndSecond = 59,
Interval = 5
};
var myTimerJob =
new MyTimerJob(
string.Format(MyCustomTimerJobName,
web.Url), web.Site.WebApplication,
null, SPJobLockType.Job)
{ Schedule = schedule };
// add properties to determine which site and web
// the timer job handles
myTimerJob.Properties.Add("site-id", web.Site.ID);
myTimerJob.Properties.Add("web-id", web.ID);
myTimerJob.Update();
}
finally
{
// SET THE REMOTE ADMINISTATOR ACCESS DENIED BACK WHAT
// IT WAS
SPWebService.ContentService.
RemoteAdministratorAccessDenied =
remoteAdministratorAccessDenied;
}
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties
properties)
{
using (var web = properties.Feature.Parent as SPWeb)
{
if (web == null) return;
// THE ORIGINAL VALUE OF REMOTE ADMINISTRATOR
var remoteAdministratorAccessDenied =
SPWebService.ContentService.
RemoteAdministratorAccessDenied;
try
{
// SET THE REMOTE ADMINISTATOR ACCESS DENIED FALSE
SPWebService.ContentService.
RemoteAdministratorAccessDenied = false;
// delete the custom timer job if it exists
var app = web.Site.WebApplication;
foreach (var job in
app.JobDefinitions.Where(job =>
job.Name == string.Format(MyCustomTimerJobName,
web.Url)))
{
job.Delete();
}
}
finally
{
// SET THE REMOTE ADMINISTATOR ACCESS DENIED BACK WHAT
// IT WAS
SPWebService.ContentService.
RemoteAdministratorAccessDenied =
remoteAdministratorAccessDenied;
}
}
}
}
The idea is that remote administration is allowed (SPWebService.ContentService.RemoteAdministratorAccessDenied = false) for the period of time the custom timer job is either installed (activated) or deleted (deactivated) and it’s set back to what it was at the end.
Below is a custom timer job stub just to make the point complete:
{
public MyTimerJob()
{
}
public MyTimerJob(string name, SPService service, SPServer server,
SPJobLockType lockType)
: base(name, service, server, lockType){}
public MyTimerJob(string name, SPWebApplication webApplication,
SPServer server, SPJobLockType lockType)
: base(name, webApplication, server, lockType){}
public override void Execute(Guid targetInstanceId)
{
if (!Properties.ContainsKey("site-id") ||
!Properties.ContainsKey("web-id"))
return;
var siteId = (Guid)Properties["site-id"];
var webId = (Guid)Properties["web-id"];
using (var site = new SPSite(siteId))
{
using (var web = site.OpenWeb(webId))
{
// do your deeds
}
}
}
}
I made my feature hidden only to be activated via scripting to be sure no one would try to activate the feature from my content web application’s UI.
The sample about creating custom timer jobs in msdn (also linked in Stef’s post) article installs the custom timer job via WebApplication-scoped feature. I think timer jobs are only meant to be installed in Central Admin’s context but then how could you fluently develop timer jobs that handle something in your content applications if you can’t install timer jobs per site or web.
The workaround is however something I would’t have wanted to find out, nor use, so use it with your own risk.
Popularity: 10% [?]
If you are looking for sexy chat contacts with hot ladies in EU you must to visit kostenloser sexchat
Transexuel Toulouse is great web platform for casual chat experience with fine ladies in France
shemale rennes is great place for your own sexy chat pleasure with hot girls in France
If you are alone check fine girls at the best web platform omas suchen sex
Annunci trans a Roma is probably the best web platform for free chat with local girls in Italy, so check out and enjoy
Our vast expertise has enabled us to have a deeper understanding of the specifics involved in the concreting procedure, see more..
Italian ladies waiting for casual contacts with you Shemale Palermo