何小碩's profileGet More... ExperiencePhotosBlogListsMore Tools Help

Blog


    June 22

    MOSS 2007 邏輯架構佈署

    Overview

    Planning and installing SharePoint Farm across enterprise network is not a trivial task. SharePoint is rarely installed in an isolated environment, and usually it interferes with the organization strategy and existing infrastructure. Many factors may affect farm design, performance, scalability and redundancy - from hardware devices in organization network, to network topology. As a result, leveraging and finding compromises among those factors helps to build consistent, reliable and flexible environment.
    There are several whitepapers on the Microsoft TechNet portal describing requirements for SharePoint Farm, but most of them are either written without taking into account infrastructure scope or filled with irrelevant information that navigate the reader away from the problem scope.

    In this document you will find the configuration recommendations regarding different SharePoint areas. All information is represented in the set of recommendations about different actions you need to undertake or pay additional attention when you install and configure your SharePoint environment. We tried to structure all section to follow the natural flow of SharePoint installation from the scratch - from pre-installing analysis requirements to post deployment actions.

    We plan several whitepapers in our “Best Practices” series, and we are interested which topis you would like to see in our next SharePoint publications. Please send us your comments and suggestions via this form.

    Introduction

    Organizations adopting SharePoint face a variety of tasks - from planning, strategy, infrastructure and architecture design, UI Design, migration, and to development. All these tasks imply flexible infrastructural baseline before actual work starts. However, in reality we face the outdated environment and misconfigured farms that are not ready to implement new requirements. In such cases, baseline architecture becomes foundation stone of all SharePoint projects.
    Why would we care about infrastructure and not about something else, for example development? Fixing infrastructure errors is very expensive task and leads into significant changes across SharePoint farm. For example, Index Role assigned to the wrong server and incorrectly configured Search can lead to performance and redundancy issues that might require up to 3 days fix. Development errors are not so expensive and can be fixed relatively quickly, but sometime such errors, eventually become infrastructure errors that lead to changes in infrastructure design.

    article1-planning

    “Architectural Planning”

    Plan your farm and network communications before starting actual installation. The first thing to start is designing SharePoint architecture across corporate network. This includes understanding network structure, examining network devices and choosing the right SharePoint topology to fit the existing infrastructure and new requirements.

    Examine corporate network

    Start from description of the existing network design, location of all applications and system servers. Microsoft Visio 2007 and “Network Diagram” template is a good instrument for this task.

    Record the location and information of corporate system servers, like Domain Controllers, File Servers, Mail Servers, Application and others. Dont’ forget about network services - firewalls, proxies, and etc. For example, locations of ISA Servers across corporate network - IP address, list of open ports and the administrative user.

    The best way to maintain “Network Diagram” document is to update the single diagram that covers topology of all domains and how they are connected. The following diagram demonstrates the Visio document descibing the servers and devices across organization.

    serverslocation

    This diagram will give a holistic view of the existing topology and ensure quick access to information across different domains.

    Examine network devices

    All network devices in the topology play a vital role of how SharePoint performs and interacts among different servers. Information about locations and settings of all routers, switches, and accelerators become very important in planning server locations. For example, location of different WAN and XML accelerators across network affects SharePoint server organization and configuration.

    Presence of different network devices affects the connection bandwidth and latency between farm’s servers, and thereby, affects the choice of appropriate SharePoint Farm topology. Network Load Balancers (NLB), routers and switches will affect how fast network response, therefore the farm should be designed with the least impact of these devices.

    Refer to the following links for the detailed information about WAN accelerators, NLB and other network devices across SharePoint farms:

    1. http://technet.microsoft.com/en-us/library/cc263099.aspx
    2. http://blogs.msdn.com/joelo/archive/2008/01/17/global-sharepoint-deployment-partner-solutions.aspx
    3. http://blogs.msdn.com/joelo/archive/2007/01/05/nlb-network-load-balancing-and-sharepoint-troubleshooting-and-configuration-tips.aspx

    Network administrator is a friend

    The IT administrator is the person who should participate in farm configuration from the very beginning. This person will be responsible for the configuration of all network servers and devices across corporate network.

    Most of the SharePoint Farm topologies cross the bounds of domains and from the very beginning specific protocols and ports must be open. The best way to maintain current situation is to have a separate document, shared with administrator, with the description of protocols and ports to open across network services.

    Detailed information about system accounts and list of ports is available in the following articles:

    Measure network latency

    Network response time is one of the important factors that can affect SharePoint farm design. Ideally, you need to measure the latency between SharePoint servers and users in order to reorganize servers according the smallest response time.

    Network latency is the key point to determine which of the proposed scenarios to implement in the current SharePoint deployment. (Latency is the time required for a packet to travel from one point on a network to another).

    Use the Ping tool (ping.exe) to measure latency for:

    • users - from the client computer to the Web server on the server farm;
    • data centres that host servers of the same farm - from a Web server in the remote data centre to the database server in the primary data centre

    Do not forget to divide the round-trip result by two, because all measures are one way only, not round-trip.

    Compare results to the data below, and adopt environment to have latency lower those values.

    Number of users Concurrent users (10%) Central Solution Distributed solution
    100-5,000 10-500 Bandwidth:   3+ Mbps (dual T1)Latency:   < 100 ms Bandwidth:   1.5 Mbps (T1)Latency:   <100 ms
    10,000 1,000 Bandwidth:     3+ Mbps (dual T1)Latency:   <250 ms Bandwidth:   1.5 Mbps (T1)Latency:   <500 ms
    100,000 10,000 Bandwidth:   3+ Mbps (dual T1)Latency:   < 250 ms Bandwidth:   1.5 Mbps (T1)Latency:   <500 ms

    The critical bandwidth for any SharePoint farms is 1.5 Mbps (T1) with 500ms latency. Overstepping these values will increase the page-load times dramatically, in 4 times at least. Refer to the diagrams in the “Plan for bandwidth Requirements” document, for more details about the bandwidth and latency results under different conditions.

    Available network bandwidth and latency influences geographic deployments significantly. Data transfers across WAN links that span multiple cities, states, provinces, countries, or continents requires really fast lines to provide adequate response time, so design such topologies thoroughly.

    More details for bandwidth requirements available in the following article http://technet.microsoft.com/en-us/library/cc262952.aspx

    Become familiar with SharePoint farm communications

    Before discussing servers’ redundancy and farm topologies let us review farm servers and how they communicate with each other. The following picture from from “Planning an Extranet Environment for Office SharePoint Server” TechNet article illustrates the communication channels within a server farm and which servers handle client’s request.

    serverscommunications

    When a user issues a query, the query is sent to a Web server. The Web server communicates with the query server to build a list of results, and then communicates with the computer running Microsoft SQL Server to extend the list of results with summarization text, URLs, and security trimming. In parallel, the Web Server gets page data from SQL Server and renders them on fly. This diagram will help in understanding which roles to use on farm servers.

    Plan a baseline topology

    Analyse the existing infrastructure and plan a SharePoint topology for redundancy. The term redundancy is often misinterpreted to be synonymous with availability.

    Redundancy refers to the use of multiple servers in a load-balanced environment for any of several purposes, such as to improve farm performance, to scale out to accommodate additional users, and to improve availability.
    Availability is a more specialized concept that refers to a multiple-server environment that is designed to accept connections and operate normally even when one or more of the servers in the farm are not operational. Therefore, availability implies redundancy.

    There are several different topologies - from three to six servers in farm, which can be used as a baseline. Which one to choose depends on the level of redundancy and available hardware. Not all clients can afford topology with six or ten servers in farm due to budget limitation or data centre capabilities. Finding the compromise between numbers of servers, type of hosting and servers’ roles become critical task, because this choice will affect performance and extensibility of the SharePoint farm for several years ahead.

    Three Servers Farm

    The minimum availability for the farm with few servers can be achieved with “3-servers farm” topology. In the current topology Web and Application Servers locate together on the one box and the database is on another box. The remaining, third, server gives a choice of which server role make redundant - Web server role or the database server role.

    threeserversfarm

    The farm with the two Web Servers provides redundancy of the Web and Application roles, improving the overall performance. A drawback of this design is that your data is not redundant (left farm). In other case, farm with two Database Servers (cluster) provides data redundancy, increasing availability of critical data, but users might suffer from temporary loss of access, when Web Server unavailable (right farm).

    The “3-servers farm” is one of the most questionable farms in terms of redundancy and performance. This limitation in the number of servers cannot provide redundancy of Query Server and high performance at the same time.

    Redundancy can be achieved with Query Roles on both Web App servers. In this case, Database Server is the only place for Index Role, but this will hinder the overall performance. The Index Role is very CPU and HDD consuming role and that is why database servers are not very optimal place for this role. Alternative solution is to assign Index Role to the Web Server with the Query Role, but this will not work effectively, because in this case, index will not be propagated to another Query Server in farm.

    If performance is one of the priorities then consider using Query Server and Index Server Roles on different Web Application Servers. This is flexible design in terms of extensibility, because with the new servers in farm changing roles of Index and Query servers is not required.

    Interestingly, a TechNet article (http://is.gd/8QbS, page 26) explains, that a Query Server can’t be used with Web Applications server for 3-servers farm. The reality is that, Web App and Query Role together are super common, more common than not (one of the reasons is that Query Server doesn’t use Network-Load Balancer - it uses its own algorithm).  What they actually mean in the TechNet article is that having the  Index on database server is not at all a recommended solution.

    Four Servers Farm

    Additional, forth server will add redundancy either for Data Server or for Web Server. However, it does not help much with performance. Current topology suffers from the same “3-servers farm” drawbacks - no place for Index Server with Query Role redundancy.

    Five+ Servers Farm

    The most common and highly available server farm topology is “5+ servers farm”, the farm with the middle tier server.

    fiveserversfarm

    This middle tier server solves all issues of three and four servers topology by providing the dedicated tier for Index and Application roles. Additional servers in farm will extend middle tier, by assigning new roles to those servers - Excel Calculation Services Role, and Microsoft Office Project Server 2007 Role.

    The following table summarize farm topology:

    Farm Servers

    Performance

    Redundancy

    3 - 4

    Index on WFE with Query on another boxApp Roles on WFE Index on Database, with Query on WFEApp Roles on WFE

    5

    App Roles on Middle TierDedicated Index Server on Middle Tier App Roles on WFEDedicated Index Server on Middle Tier

    6

    Dedicated Web Server for Crawling, outside NLBDedicated Index Server on Middle Tier App Roles on Middle Tier in NLBDedicated Index Server on Middle Tier

    To optimize the overall performance of five and more servers SharePoint Farm, configure a dedicated Web Server for crawling content, especially when crawling a server farm that contains more than 500 gigabytes (GB) of content or crawling content over the WAN. To ensure that user requests are not affected by content crawling, remove the dedicated Web server from the network load balancing rotation. This is especially important in global environments in which the off-peak hours of a regional farm (when crawl jobs are likely to be schedule) coincide with the peak hours of the central farm.

    Plan extranet topology

    Choose the topology based on requirements for external users. This topology will provide a basis of network extensibility for applications servers and communications between them.

    The simplest topology is “Edge firewall topology”, which is represented by following diagram, from TechNet article.

    edgetopology

    This topology applicable for the small farms, when there is no need to separate internal services from corporate network and secure communications between server farms. All remote users are separated from farm by ISA server which plays a role of remote proxy.

    For the big farms, when security of communications is a priority, the recommended topology is “Back-to-back perimeter topology”. This is very flexible and adaptable topology for network changes.

    backendtopology

    The main advantage of this topology is that it isolates the server farm in a separate perimeter network. Layers logically separate all servers and communications are under control - any security damages affect only specific layer, not the entire farm. External user access is isolated to the perimeter network and users can be isolated in different AD for remote and corporate access.

    There are some other extranet topology variations, but mostly all of them are based on “Back-to-back perimeter topology” with some modification.

    Detailed information about farm topologies can be found in the following documents:

    1. Best practices for My Sites: http://technet.microsoft.com/en-us/library/cc262706.aspx
    2. Best practices for team collaboration sites: http://technet.microsoft.com/en-us/library/cc850694.aspx
    3. Planning an Extranet Environment for Office SharePoint Server: http://technet.microsoft.com/en-us/library/cc262400.aspx

    “Logical Planning”

    Plan site collections

    Plan number of site collections and sub sites in advance - content, location, security. Start with the single site collections and several sub sites rather then creating several site collections, and try to avoid new site collection if there are no requirements for this. The reason of such structure is that each new site collection works as a new application, with isolated scope to features, templates and search. Maintaining such structure is much easier than several site collections.

    Organize site collection across several content databases

    Do not end up with one big content database, because data optimisation will cause troubles in this case. For the small and development environments, single content database might be a preferable choice. However, for the large farms create several content databases and organize site collections among them. Having several content databases with sites helps to address the following:

    • Keep content database size <100 GB, otherwise it could hinder performance (MS recommendation)
    • Data usage optimization.
    • Simplify farm backup and restoration.
    • Flexibility for Disaster Recovery (DR) strategies.

    More details about site collections in several content databases available in the following blog post: http://msmvps.com/blogs/laflour/archive/2008/10/14/tips-to-create-a-site-collection-in-new-content-database.aspx

    Script actions

    Prefer to script installation and SharePoint Farm configuration actions: setting roles, creating web sites and site collections, etc. Configuring successful farm from the first attempt has a change to fail due to complexity of SharePoint. Running scripts to repeat all actions will save time when something went wrong and new server installation is required.


    In the next part we will review the actual SharePoint installation and the basic farm configuration.

    This entry was posted on Thursday, June 4th, 2009 at 1:00 am and is filed under Administration, Technical. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

    客戶端專案開發廠商開發環境說明

    Virtualization in SharePoint farm is one of the key design factors that simplify server availability by providing number of additional servers that might not be available over physical server models, or solution become very expensive. Microsoft officially supports SharePoint farm in virtualized environment since mid 2007. The following virtualizations technologies are supported: Hyper-V, Virtual PC, Virtual Server and 3rd party providers like VMware.

    One of the key factors for virtualization is that performance of virtualized farm is competitive to the physical farm. Microsoft tests shows:
    - 7.2% less throughput on virtual Web roles with 8GB of RAM than a physical Web role server with 32GB of RAM;
    - 4.4% slower in the page response time on the Hyper-V Web front-end than the physical server;

    Virtualize SharePoint Web Role

    Web front-end servers are responsible for the content rendering and have comparatively lower memory requirements and disk activity than other roles, what makes them is an ideal candidate for virtualization.

    Choose disk type for Query Role

    The query role is responsible for a search performed by users is a good candidate for virtualization. The disk type choice for this role depends on the size of propagated index and the rate of index propagation.
    The recommendation for the large indexes and the farm with the high rate of the updated information to use a physical disk volume that is dedicated for the individual query server, rather than a virtual disk file.

    Consider using Index Role on physical server

    The Index server role in a SharePoint farm is often the most memory-intensive role, what makes it less ideal candidate for virtualization. Virtualized Index server role might be appropriate for development environment, small farm or farm with small content usage.
    Take into account, that index can vary from 10% to 30% of the total size of the documents being indexed. For the large indexes (above 200 GB) consider using physical disk volume that is dedicated to the individual query server, rather than virtual disk.
    For large farms with big amount of crawled data use physical Index server role due to large memory requirements and high disk I/O activity.

    Do not virtualize Database role

    SharePoint database role is the least appropriate role for virtualization in production scenarios, mainly due to the highest amount of disk I/O activity and very high memory and processor requirements. However, it is very common to see the SQL Server virtualized in test farms, quality assurance (QA) farms, and smaller SharePoint environments.

    Do I need to virtualize Application role?

    The decision of virtualizations the application roles, such Excel Services and InfoPath Services, depends on the roles usage. Those roles can be easily virtualized, because they are similar to Web Roles and mostly CPU intensive. When necessary, those servers can be easily moved to dedicated physical servers.

    Virtualized scenario sample

    The following picture demonstrates the common virtualized scenario of SharePoint Farm.

    virtualization

    Common deployment scenarios for the SQL role in a SharePoint farm may have multiple farms, both physical and virtual, use a single database server or database cluster, further increasing the amount of resources consumed by the role. For example, in the picture above, the sample SharePoint environment illustrated maintains a two-server SQL cluster that is used by several virtual farms and one production farm.

    Use proper number of CPU

    Do not use more virtual CPUs than physical CPUs on the virtual host computer - this will cause performance issues, because the hypervisor software has to swap out CPU contexts.
    The best performance can be realized if the number of virtual processors allocated to running guests does not exceed the number of logical processors (physical processors multiplied by the number of cores) on the host. For example, a four processor quad-core server will be able to allocate up to 16 virtual processors across its running sessions without any significant performance impact. Note that this only applies to sessions that are physically running simultaneously.

    Use proper amount of RAM

    Plan to allocate the memory on virtual sessions according the next rule - divide the total amount of RAM in the server by the number of logical processors (physical processors multiplied by number of cores) in the host server. This will align allocated memory along with NUMA sessions. Otherwise it will provide performance issues.
    In some testing, a virtual SharePoint Web server role with an allocation of 32GB of RAM actually performed worse than a virtual server with an allocation of 8GB of RAM.

    Plan to use physical drives

    In virtual scenarios front-end Web servers or Query servers disk performance is not as important as it would be physicals servers of the Index role or a SQL Server database. A fixed-size virtual disk typical provides better performance than a dynamically-sized disk.
    If disk speed is a high priority, consider adding physical drives to the host computer. Add new virtual hard drive and map it to an unused physical drive on the host. This configuration, called a “pass-through disk”, is likely to give the best overall disk throughput.

    Consider using hardware load balancing

    Hardware load balancing provides the best performance, comparing with the software load balancing. It offloads CPU and I/O pressure from the WFE’s to hardware layer thereby improving availability of resources to SharePoint. Examples of Hardware: F5 BIG IP, Citrix Netscaler, Cisco Content Switch. Software load balancing examples are Windows Network load balancing, Round Robin load balancing with DNS. It is a trade-off between cost and performance. (Additional details are here)

    Be careful with snapshot feature on virtual servers

    Using snapshots for the backup might cause you troubles, because SharePoint timer service might be  unsynchronized during the snapshot process, and once the snapshot is finished, errors or inconsistencies can arise. So, consider backups over the snapshots for the production environments.

    Measure virtualized environment performance

    After you complete your virtualized environment installation and configuration measure how fast you environment operates and optimize it to the best performance. Measure the following parameters:
    1) Processor performance - “\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time” performance monitor counter.
    Results: <60% Utilization is fine, 60%-89% - caution, > 90% significant performance degradation
    2) Memory performance - “\Memory\Available Mbytes” of the physical memory available to processes running on the computer, as a percentage of physical memory installed on the computer.
    Results: 50% is fine, 10% and below is critical
    3) Disk performance - “\Logical Disk(*)\Avg. Disk sec/Read” or “\Logical Disk(*)\Avg. Disk sec/Write” disk latency on the Hyper-V host operating system.
    Results: up to 15ms is fine, 15ms-25ms is warning, >26ms critical

    Mode details about virtualized performance counters can be found in this post

    Refer to the following document for more details regarding virtualization: http://technet.microsoft.com/en-us/library/cc816955.aspx


    In the next, final part we will describe the post deployment steps, which should be done to clear farm from temporary stuff and make your farm ready for production.

     

    This entry was posted on Monday, June 22nd, 2009 at 8:37 am and is filed under Administration, Technical. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

    June 17

    When you install the 2007 Microsoft Office servers Service Pack 2, the product expiration date is activated incorrectly(KB 971620)

    Source: Microsoft Support

    SYMPTOMS

    During the installation of the 2007 Microsoft Office servers Service Pack 2, a product expiration date is activated incorrectly. This means that any of the products that are listed in the "Applies to" section will expire 180 days after Service Pack 2 is deployed, as if it were a trial installation. The activation of the expiration date will not affect the regular function of these products until the expiration date passes, 180 days after Service Pack 2 is deployed. If the product expires, it will not affect data, configuration, or application code. However, it will make the Office Server product inaccessible for end-users.
    Office SharePoint Server Trial with Enterprise Client Access License, or a similar product, is displayed on the Convert License page.

    CAUSE

    This issue occurs because of the installation of the 2007 Microsoft Office serve...

    This issue occurs because of the installation of the 2007 Microsoft Office servers Service Pack 2. All installations of this service pack will result in this issue.

    RESOLUTION

    To resolve this issue manually, type the product key on the Convert License Type...

    To resolve this issue manually, type the product key on the Convert License Type page. To do this, follow these steps:

    1. Click Start, point to All Programs, point to Administrative Tools, and then click SharePoint 3.0 Central Administration.
    2. Click the Operations tab.
    3. Click Convert License Type.
    4. In the Enter the Product Key text box, type your product identification number, and then click OK.
    5. The License Synchronizer Job will run on all computers in the farm after a few moments. After all the computers have updated their license from the timer job, the Convert License Type page will reflect the correct license.
    If you do not have your product key, you can retrieve it by logging on to the Volume Licensing Service Center (https://www.microsoft.com/licensing/servicecenter/home.aspx) .

    June 14

    What every SharePoint administrator needs to know about Alternate Access Mappings (Part 1 of 3)

    Hi folks, this is Troy Starr again from the Windows SharePoint Services Test team. Today I'd like to talk about one of the most powerful, but often one of the least understood, features in Windows SharePoint Services 3.0 and Microsoft Office SharePoint Server 2007. That feature is called Alternate Access Mappings. Around here, we just call it "AAM" for short.

    At the most basic level, AAM tells SharePoint how to map web requests (for example, browsing to the homepage of a SharePoint site) to the correct web application and site so that SharePoint can serve the correct content back to you. It then tells SharePoint what URL the users should be taken to as they interact with SharePoint.

    Seems simple enough, doesn’t it? Those of you who are familiar with developing web applications in Internet Information Services may be wondering right now why we need such a feature since IIS can tell you what the URL of an incoming web request is. The major reason we need this is that there are common Internet deployment scenarios where the URL of a web request received by IIS is not the same URL that the end user entered. These are most common in reverse proxy publishing and load balancing scenarios.

    How is this possible? Let's consider a reverse proxy scenario. A reverse proxy is a device that sits between end users and your web server. All requests to your web server are first received by the reverse proxy device, and if those requests pass the proxy's security filtering, the proxy will forward the requests on to your web server. Reverse proxies can perform advanced functionality such as receiving a web request over the Internet via SSL (HTTPS), but forward the request to the your server via HTTP. This is referred to as off-box SSL termination. They can also forward the request to a different port number than it was originally received on and can even change the HTTP Host header field. If SharePoint were base its links off of the URL of the request it received, the links that end users click on could be the incorrect "internal" URL rather than the correct "public" URL.

    SharePoint is compatible with a variety of reverse proxy servers, but for this example we'll take a look at a publishing rule from Microsoft's reverse proxy software - Internet Security and Acceleration Server 2006. ISA Server 2006 includes a SharePoint publishing wizard that walks you through creating a publishing rule for SharePoint. Once the rule is created, you can modify it at any time. (The following images show a slightly modified publishing rule where the "Forward the original host header" option is turned off to help demonstrate the flexibility of AAM. If we left the "Forward the original host header" option turned on, the public hostname would also serve as the internal hostname when configuring AAM.) The first two dialogs show the "listener" and "public name" properties of the rule, which define what URL users will use to access your SharePoint site. Remember that this URL is really the URL of your reverse proxy server, which will forward the request to your SharePoint server.
    listener highlighted.PNGpublic name highlighted.png

    The end user's URL is comprised of the public protocol, the public hostname, and the public port number.

    Public Protocol

    +

    "://"

    +

    Public Hostname

    +

    ":"

    +

    Public Port Number

    =

    Public URL

    HTTPS

    www.contoso.com

    443

    https://www.contoso.com

    The next two dialogs show the "to" and "bridging" properties of the rule, which define what URL the reverse proxy server will use to forward the request to your SharePoint server.

    bridging highlighted.pngto highlighted.png

    The SharePoint server's URL is comprised of the internal protocol, the internal hostname, and the internal port number.

    Internal Protocol

    +

    "://"

    +

    Internal Hostname

    +

    ":"

    +

    Internal Port Number

    =

    Internal URL

    HTTP

    sharepoint.dmz.contoso.com

    80

    http://sharepoint.dmz.contoso.com

    extend web application highlighted.png

    Great - we've properly set up this reverse proxy server to receive web requests from end users at https://www.contoso.com and forward them to your SharePoint server at http://sharepoint.dmz.contoso.com. We're halfway there! The next step is to configure your SharePoint web application and AAM to match the publishing rule above. To do this, we'll extend an existing web application to an additional IIS Web site just for your reverse proxy's publishing rule. Note that you're also able to create a new web application from scratch for this publishing rule - the fields you'll need to fill out are the same in either case.

    Browse to your WSS 3.0 Central Administration site and click on the Application Management tab. Next, click "Create or extend Web application" and then click "Extend an existing Web application." Select the web application that you wish to use, and then fill out the port, host header, and SSL fields based on the internal URL properties that we defined above. In the URL field, enter the public URL that we defined above. Finally, you'll want to select an AAM Zone to assign this extension of your web application to. There are a maximum of 5 zones available in each web application. We'll use the Internet zone in this example, but you're free to use any available zone. All of the zones provide the same functionality, although the Default zone will always be used for certain features such as sending administrative e-mail messages to site collection owners. When you're finished, click OK to create the IIS Web site.

    Next, you'll want to verify that your public URL was created correctly in AAM and then add your internal URL. Unless your internal URL is the same as your public URL, this is an extra step that you must perform manually. To do this, browse to your WSS 3.0 Central Administration site and click on the Operations tab. Next, click "Alternate access mappings." Click the Alternate Access Mappings selector drop-down and select the web application that you're publishing through your reverse proxy server. You should now see the AAM URLs assigned to your web application.

    AAM before.png

    As you can see, the public URL from the reverse proxy publishing rule has been assigned to your web application's Internet zone. The final touch is to add the internal URL from the reverse proxy publishing rule to your web application's Internet zone. To do this, click "Add Internal URLs" in the AAM toolbar, type in the internal URL, and select the same zone that you used for the public URL. In this case, that was the Internet zone. When you're finished, click Save. You should now see the additional URL is assigned to your web application, in the same zone as the public URL of your reverse proxy publishing rule.

    AAM after.png

    All done! Now, when a user browses to https://www.contoso.com, the web request will be received by the proxy server and forwarded to http://sharepoint.dmz.contoso.com. SharePoint will then receive the web request, see that the URL of the request is http://sharepoint.dmz.contoso.com, find that this URL is assigned to the Contoso web application, and return the content from that web application. In addition, because the http://sharepoint.dmz.contoso.com URL is assigned to the Internet zone, SharePoint will also generate links on the pages using the public URL for that zone - https://www.contoso.com. This ensures that end users are taken to the proper URL when clicking on links on the page.

    Load balancers work similarly, especially if they overwrite the end user's original URL with the URL of the individual web server that the request is being load balanced to. To address this, just add each individual web server's URL to AAM as an internal URL and associate them all to the same zone as end user's public URL.

    I hope that this introduction to Alternate Access Mappings was helpful to you. Please feel free to post comments to this blog entry with any questions you may have about AAM. I will be posting another blog entry soon covering common AAM mistakes and how to avoid them.

     

    Troy Starr

    Published Tuesday, March 06, 2007 5:19 PM by sptblog

    How to configure ssl for whole site with output caching enabled

    I ran into a new situation which i haven't thought about before. What if you have a public facing anonymous sharepoint site and you want to add a ssl cert for the whole site + you have output caching enabled with VaryByHeaders set to User-Agent. Most of us would handle this situation by inserting the ssl cert to the extended anonymous iis website.

    Situation: Cache flushed, first user hits https://www.contoso.com and then the second user goes to http://www.contoso.com and gets all the links pointing to the https site. This is because IIS + output caching is related to one IIS website at the time (one w3wp.exe process). Here's how to go around this issue.

    Extend the website once more and put it with the same host header as the anonymous site but map it to port 800. This is because IIS does not allow two websites with same port & host header (obviously). Then add the

    SSL cert to this new website. The picture below describes why.

    Port 800 never get hits but the website responds to the https requests.

    Published Monday, March 03, 2008 6:05 PM by jukka

    SharePoint Server 2007 articles, fixes and updates

  • 962928 You cannot browse to an SSL-secured Office SharePoint Server 2007 site or to the Search Settings page for a Shared Services Provider Q962928 KB962928 May 1, 2009
  • 929360 You cannot create a new document or check out an existing document in a Windows SharePoint Services 3.0 document library when you have multiple versions of Office installed Q929360 KB929360 May 1, 2009
  • 888237 You receive inconsistent search results when you search for content that contains a particular Chinese Traditional term in SharePoint Portal Server 2003 or in SharePoint Server 2007 Q888237 KB888237 April 17, 2009
  • 841215 You cannot connect to a document library in Windows SharePoint Services 3.0 or Windows SharePoint Services 2.0 by using Windows shell commands or by using Explorer View Q841215 KB841215 March 19, 2009
  • 967612 You cannot limit the People Picker on the site-collection level to find only users in a specific organization unit (OU) in a trusted domain in a SharePoint site Q967612 KB967612 March 13, 2009
  • 961138 You cannot enable the Publishing feature in SharePoint Server 2007 after you delete an out-of-box standard permission level Q961138 KB961138 December 29, 2008
  • 955653 You may experience poor performance when you use many SetCell calls in Excel Services Q955653 KB955653 August 1, 2008
  • 953450 You cannot change the master page that is associated with a specific page layout in SharePoint Designer 2007 Q953450 KB953450 July 23, 2008
  • 953446 You receive alerts for every file that is uploaded to a document library in Windows SharePoint Services 3.0 or in SharePoint Server 2007, even though you set up alerts by using a filter for the custom view Q953446 KB953446 July 23, 2008
  • 951249 You do not receive search alerts when you use the FullTextSqlQuery object to perform a full-text search of a server that is running SharePoint Server 2007 Q951249 KB951249 July 8, 2008
  • 932619 You cannot crawl case-sensitive Web content in SharePoint Server 2007 Q932619 KB932619 July 7, 2008
  • 909506 You cannot view a list in Datasheet view on a Windows SharePoint Services Web site Q909506 KB909506 July 1, 2008
  • 953455 You cannot create subsites that can inherit permissions when you do not have “Manage Web Site” permissions in Windows SharePoint Services 3.0 Q953455 KB953455 June 13, 2008
  • 952171 You are prompted multiple times for authentication when you try to access Central Administration, or you receive an error message when you try to configure the Office SharePoint Server Search service in SharePoint Server 2007 Q952171 KB952171 May 5, 2008
  • 949003 You are directed to an English Web site even though you created the Web site in a different language in SharePoint Server 2007 Q949003 KB949003 March 18, 2008
  • 948324 You cannot use the ItemUpdating event to retrieve an updated value in SharePoint Server 2007 or in Windows SharePoint Services 3.0 Q948324 KB948324 March 14, 2008
  • 945967 You receive an error message when you try to install a slipstream installation of Microsoft Search Server 2008 or SharePoint Server 2007 on a server that is running Windows SharePoint Services 3.0 Q945967 KB945967 March 12, 2008
  • 948323 You receive an Event ID 6875 error message when you publish a page in Microsoft Office SharePoint Server 2007 or in Windows SharePoint Services 3.0 Q948323 KB948323 February 27, 2008
  • 944299 You receive unexpected search results when lots of groups and users access a SharePoint Server 2007 or a Windows SharePoint Services 3.0 site Q944299 KB944299 February 18, 2008
  • 941861 You may see duplicate entries in the View Reports feature after you import or export a site collection in SharePoint Server 2007 Q941861 KB941861 February 14, 2008
  • 946791 You cannot install SharePoint Server 2007 or SharePoint Portal Server 2003 when you are running SQL Server in a geographically dispersed cluster environment Q946791 KB946791 January 17, 2008
  • 941836 You are prompted to approve a connection to a SharePoint feature in Outlook 2003 Q941836 KB941836 January 15, 2008
  • 823278 You receive an "Access denied" or a "Cannot complete this action" error message when you try to connect to a Windows SharePoint Services Web site Q823278 KB823278 December 4, 2007
  • 934536 You cannot create a list that is based on a list template that has the E-Mail Notification option enabled in Windows SharePoint Services 3.0 or in SharePoint Server 2007 Q934536 KB934536 October 31, 2007
  • 828813 You receive a "Specified domain does not exist" or an "Adding user name failed" error message when you extend a virtual server with Windows SharePoint Services 2.0 Q828813 KB828813 October 23, 2007
  • 942620 You receive an error message when you try to install the 2007 Microsoft Office servers Service Pack 1 on a computer that does not have Windows SharePoint Services 3.0 Service Pack 1 installed Q942620 KB942620 October 18, 2007
  • 930887 You experience issues with portal alerts in SharePoint Portal Server 2003 or with search performance in SharePoint Server 2007 after you create SQL Server 2005 maintenance plans Q930887 KB930887 October 15, 2007
  • 941006 You must press CTRL+C to close the Operation Completed Successfully dialog box when you import or export SharePoint Server 2007 site data on a computer that is running Forefront Security for SharePoint Q941006 KB941006 October 8, 2007
  • 826797 You cannot search for content, or you may receive unexpected results when you search for content in the portal site in SharePoint Server 2007 or in SharePoint Portal Server 2003 Q826797 KB826797 September 27, 2007
  • 941789 You receive error messages after you install security update 931212 (MS07-040) on a Windows SharePoint Services 3.0 Web front-end server or on a SharePoint Server 2007 Web front-end server Q941789 KB941789 August 30, 2007
  • 894630 You receive a "The specified file or folder name is too long" error message when you create a new folder or a new document in a document library in SharePoint Portal Server or in Windows SharePoint Services Q894630 KB894630 August 20, 2007
  • 937949 You cannot upgrade SharePoint Portal Server 2003 to SharePoint Server 2007, and you receive an error message when you run the Prescan.exe tool Q937949 KB937949 June 12, 2007
  • 899709 You receive a "<FileName> is locked for editing by 'another user'" message when you try to modify a document in Windows SharePoint Services even though you are the user who previously opened the document Q899709 KB899709 May 17, 2007
  • 928753 You cannot locate an Excel 2007 workbook when you specify http://localhost in the workbook URL parameter for an Excel Web Access Web Part Q928753 KB928753 May 14, 2007
  • 928742 You cannot load an Excel 2007 workbook in Excel Web Access when a SharePoint Server 2007 Web site uses Basic authentication and when the trusted file location type is set to HTTP Q928742 KB928742 May 14, 2007
  • 928730 You may expose internal server names or path names when you post an Excel 2007 file to a SharePoint Server 2007 Web site if the file uses a CELL(<address>) function Q928730 KB928730 May 14, 2007
  • 928728 You receive an error message when you use Excel Web Access to refresh the data connections for an Excel 2007 workbook Q928728 KB928728 May 14, 2007
  • 928304 You cannot select a new index server on the "Edit Shared Services Provider" page in SharePoint Server 2007 Q928304 KB928304 May 14, 2007
  • 928035 You cannot add an alert or a new item to the Document ID Log Report in SharePoint Server 2007 Q928035 KB928035 May 14, 2007
  • 926328 You can use the cd command or the chdir command to change to a subfolder of a WebDAV shared folder even though the subfolder does not exist in Windows SharePoint Services 3.0 Q926328 KB926328 May 14, 2007
  • 926202 You cannot change your user information on the "My Settings" page in SharePoint Server 2007 Q926202 KB926202 May 14, 2007
  • 924464 You do not see a link to the home page of the portal site in a personal site that you created in SharePoint Server 2007 Q924464 KB924464 May 14, 2007
  • 919547 You cannot log on to a SharePoint Server 2007 site after you change the computer that is used as the dedicated front-end Web server Q919547 KB919547 May 14, 2007
  • 871155 You are prompted to enter your user name and your password when you open an Office document in SharePoint Server 2007, in SharePoint Portal Server 2003, or in Windows SharePoint Services Q871155 KB871155 March 29, 2007
  • 827920 You receive an "Error 502" error message, or the Web page is not displayed when you try to access SharePoint Central Administration pages after you install SharePoint Portal Server 2007 or SharePoint Portal Server 2003 on a stand-alone computer Q827920 KB827920 March 29, 2007
  • 828814 You receive a "There is no such object on the server" error message when you extend your Windows SharePoint Services virtual server Q828814 KB828814 February 21, 2007
  • 928783 You receive different results on an Office SharePoint Server 2007 server than on a client computer for an Office Excel 2007 workbook when you use a managed-code user-defined function in the workbook Q928783 KB928783 January 11, 2007
  • 923522 You receive an error message when you deactivate or remove a form from a form server Q923522 KB923522 November 21, 2006
  • Search and Indexing UNC Folder

    In this post I will show you how to configure search by creating a content source that should be indexed and a search scope to limit the results when searcing. I will also show you how to customize the Search Center and adding a tab with a custom search and search results page.

    I will walk you though how to set up searchscopes and content sources (such as fileshares).

    We will begin by creating a content source and a search scope This will presume that you’ve got a network share with files and folders, e.g. the share “\\whatever\someShare” mapped against Z:\ on your local system.

    1. Open SharePoint Central Administration and the Shared Services Provider admin site.
    2. Open the Search Settings page
    3. Choose the Content Sources link in the Crawl Settings section.
    4. Choose New Content Source in the toolbar menu
    5. Enter a name (I used “Demo Documents”)
    6. Choose File Shares as Content Source Type
    7. Enter the start address (e.g. \\whatever\someShare)
    8. Choose if it should include all subfolders or not under Crawl Settings
    9. Set a schedule of your preference and choose to start the crawl if you want, then click OK
    10. It should now look something similar to this image:11. Now you need to start the crawl, if you didn’t do so when creating the content source

    Creating a scope to narrow down the search results to only file shares
    1. Navigate to Site Settings
    2. Click on View Scopes in the Scope Settings section
    3. Click Create New Scope in the toolbar and enter e.g. “File Shares” as the name and click OK
    4. Note that the “Items” column states “Empty”.
    5. Click on the name (File Shares) to navigate to the Scope Properties and Rules page
    6. Select “Empty – Add rules”
    7. Select “Demo Documents” in the Content Scope and press OK to create the rule.
    8. Now note that it says “New Scope – Ready after the next update (starts in n minutes). To avoid this waitint time, go back to the Search Settings and click “Start Update Now” under the Scopes section.
    9. Click the Site Settings menu at the top right of this site collection and choose Search scopes
    10. Click the “Search Dropdown” display group and then check the “File Shares” scope and click OK.
    11. Go to the Search Center to validate that the scope actually works and shows in the drop down


    Posted 11-16-2006 3:17 AM by Tobias Zimmergren

    Creating a Scope and Tab for MOSS Search Center(圖)

    I am occasionally asked how to create a tab in the MOSS Search Center to search a given scope. This process is often confusing to administrators because it involves the creation of a scope, making the scope available, and then the creation of not just one, but two tabs in Search Center along with ASPX pages. Before beginning, this article assumes that you already have the Shared Services Provider (SSP) properly set up and that you have a "Search Center with Tabs" site available in your portal. For my example, I'll create a tab designed to search a specific document library that contains HR documents. Note that this article does not cover creating an "Advanced Search" capability - just a simple keyword search.

    HRDocuments

    Create the Shared Scope

    The first step is to create a Shared Scope that will target the document library. This Shared Scope will be set up in the Shared Services Provider using the following steps:

    1. On the home page of the Shared Services Administration site, click "Search Settings"
    2. On the Search Settings page, click "View Scopes"
    3. On the View Scopes page, click the "New" button
    4. On the Create Scope page
      - Enter HR Documents in the Title field
      - Leave the results page using the default page, you'll change that later
      - Click the OK button.
    5. On the View Scopes page, locate the new scope and click the "Add Rules" link
    6. On the Add Scope Rule page
      - Set the Scope Rule Type to "Web Address"
      - Set the Web Address to "Folder"
      - Enter the complete URL to the Document Library (e. g. , http://litwareinc.com/HR/HR%20Documents).
      - Click the OK button.
    7. Return to the Search Settings page
    8. Under the Scopes section, click the "Start Updates Now" link

    When you have completed creating the scope and updating it, you should be able to see that it contains a number of documents. This is a good check that you have created the scope correctly and it contains the number of documents that you expect.

    CompletedScope

    Make the Shared Scope Available in the Site Collection

    An optional step is to make the new scope available to the site collection where the Search Center is located. Follow these steps to do that:

    1. From the home page of your portal, select Site Actions>>Site Settings>>Modify All Site Settings
    2. On the Site Settings page, under the Site Collection Administration page, click the "Search Scopes" link

    On the View Scopes page, you should see the new scope listed under the Unused Scopes section. At this point, you could easily add the scope to the Search Dropdown that appears at the top of the page in MOSS by clicking on the "Search Dropdown" link appearing in the "Display Group: Search Dropdown" section. However, our goal is to create a tab for the search scope.

    Create the Search Center Tab

    New tabs for Search Center involve several different parts. First, you must create a search page. Then you must create a search results page. Finally, you must associate the scope with the new pages and create tabs to display them. Follow these steps to get it all working:

    1. From the Search Center page, select Site Actions>>Create Page
    2. On the Create Page
      - Enter HR Documents Search in the Title field
      - SharePoint should automatically generate a valid page name
      - Select "Search Page" from the list of available Page Layouts
      - Click the Create button
    3. A new page should now be visible with a Search Box web part
      - Select Modify Shared Web Part from the web part's edit menu
      - Expand the Miscellaneous section
      - Enter HRDocumentsResults.aspx in the Target Search Results Page URL field (you will create this page next)
      - Uncheck the box labeled "Display Advanced Search Link"
      - Click the OK button
      - Click the Publish button at the top of the page
    4. From the new page, select Site Actions>>Create Page
    5. On the Create Page
      - Enter HR Documents Search Results in the Title field
      - SharePoint should automatically generate a valid page name
      - Select "Search Results Page" from the list of available Page Layouts
      - Click the Create button
    6. A new page should now be visible with a several search web parts
      - Select Modify Shared Web Part from the Search web part's edit menu
      - Expand the Miscellaneous section
      - Enter HRDocumentsResults.aspx in the Target Search Results Page URL field
      - Uncheck the box labeled "Display Advanced Search Link"
      - Click the OK button
      - Select Modify Shared Web Part from the Search Core Results web part
      - Expand the Miscellaneous section
      - Enter HR Documents in the Scope field
      - Click the OK button
      - Click the Publish button at the top of the page
    7. From the new page, select Site Actions>>View All Site Content
    8. On the All Site Content page, click the "Tabs in Search Pages" link
    9. On the Tabs in Search Pages list, click the New button
    10. On the New Item page
      - Enter HR Documents in the Tab Name field
      - Enter HRDocumentsSearch.aspx in the Page field
      - Click the OK button
    11. From the list, select Site Actions>>View All Site Content
    12. On the All Site Content page, click the "Tabs in Search Results" link
    13. On the Tabs in Search Results list, click the New button
    14. On the New Item page
      - Enter HR Documents in the Tab Name field
      - Enter HRDocumentsSearchResults.aspx in the Page field
      - Click the OK button

    Return to the Search Center home page and you should now see a new tab visible for HR Documents.

    Search

    Try out a search and verify the expected results.

    Results

    Posted by Scot Hillier on 30-Apr-09

    Creating a Scope and Tab for MOSS Search Center

    PS: 文章中少了一個步驟, 怪了 大家的做法怎都一樣, 連台灣的書寫的也一樣, 但是客戶使用者都做不出來, 因為有少步驟ㄇㄟ@@

    I am occasionally asked how to create a tab in the MOSS Search Center to search a given scope. This process is often confusing to administrators because it involves the creation of a scope, making the scope available, and then the creation of not just one, but two tabs in Search Center along with ASPX pages. Before beginning, this article assumes that you already have the Shared Services Provider (SSP) properly set up and that you have a "Search Center with Tabs" site available in your portal. For my example, I'll create a tab designed to search a specific document library that contains HR documents. Note that this article does not cover creating an "Advanced Search" capability - just a simple keyword search.

    Create the Shared Scope

    The first step is to create a Shared Scope that will target the document library. This Shared Scope will be set up in the Shared Services Provider using the following steps:

    1. On the home page of the Shared Services Administration site, click "Search Settings"

    2. On the Search Settings page, click "View Scopes"

    3. On the View Scopes page, click the "New" button

    4. On the Create Scope page
      - Enter HR Documents in the Title field
      - Leave the results page using the default page, you'll change that later
      - Click the OK button.

    5. On the View Scopes page, locate the new scope and click the "Add Rules" link

    6. On the Add Scope Rule page
      - Set the Scope Rule Type to "Web Address"
      - Set the Web Address to "Folder"
      - Enter the complete URL to the Document Library (e. g. , http://litwareinc.com/HR/HR%20Documents).
      - Click the OK button.

    7. Return to the Search Settings page

    8. Under the Scopes section, click the "Start Updates Now" link

    When you have completed creating the scope and updating it, you should be able to see that it contains a number of documents. This is a good check that you have created the scope correctly and it contains the number of documents that you expect.

    Make the Shared Scope Available in the Site Collection

    An optional step is to make the new scope available to the site collection where the Search Center is located. Follow these steps to do that:

    1. From the home page of your portal, select Site Actions>>Site Settings>>Modify All Site Settings

    2. On the Site Settings page, under the Site Collection Administration page, click the "Search Scopes" link

    On the View Scopes page, you should see the new scope listed under the Unused Scopes section. At this point, you could easily add the scope to the Search Dropdown that appears at the top of the page in MOSS by clicking on the "Search Dropdown" link appearing in the "Display Group: Search Dropdown" section. However, our goal is to create a tab for the search scope.

    Create the Search Center Tab

    New tabs for Search Center involve several different parts. First, you must create a search page. Then you must create a search results page. Finally, you must associate the scope with the new pages and create tabs to display them. Follow these steps to get it all working:

    1. From the Search Center page, select Site Actions>>Create Page

    2. On the Create Page
      - Enter HR Documents Search in the Title field
      - SharePoint should automatically generate a valid page name
      - Select "Search Page" from the list of available Page Layouts
      - Click the Create button

    3. A new page should now be visible with a Search Box web part
      - Select Modify Shared Web Part from the web part's edit menu
      - Expand the Miscellaneous section
      - Enter HRDocumentsResults.aspx in the Target Search Results Page URL field (you will create this page next)
      - Uncheck the box labeled "Display Advanced Search Link"
      - Click the OK button
      - Click the Publish button at the top of the page

    4. From the new page, select Site Actions>>Create Page

    5. On the Create Page
      - Enter HR Documents Search Results in the Title field
      - SharePoint should automatically generate a valid page name
      - Select "Search Results Page" from the list of available Page Layouts
      - Click the Create button

    6. A new page should now be visible with a several search web parts
      - Select Modify Shared Web Part from the Search web part's edit menu
      - Expand the Miscellaneous section
      - Enter HRDocumentsResults.aspx in the Target Search Results Page URL field
      - Uncheck the box labeled "Display Advanced Search Link"
      - Click the OK button
      - Select Modify Shared Web Part from the Search Core Results web part
      - Expand the Miscellaneous section
      - Enter HR Documents in the Scope field
      - Click the OK button
      - Click the Publish button at the top of the page

    7. From the new page, select Site Actions>>View All Site Content

    8. On the All Site Content page, click the "Tabs in Search Pages" link

    9. On the Tabs in Search Pages list, click the New button

    10. On the New Item page
      - Enter HR Documents in the Tab Name field
      - Enter HRDocumentsSearch.aspx in the Page field
      - Click the OK button

    11. From the list, select Site Actions>>View All Site Content

    12. On the All Site Content page, click the "Tabs in Search Results" link

    13. On the Tabs in Search Results list, click the New button

    14. On the New Item page
      - Enter HR Documents in the Tab Name field
      - Enter HRDocumentsSearchResults.aspx in the Page field
      - Click the OK button

    Return to the Search Center home page and you should now see a new tab visible for HR Documents.

    Try out a search and verify the expected results.

    Creating an All Documents Search Scope using contentclass

    When working with customers to optimize the SharePoint Search experience, one of the first things we do is to create a scope called All Documents.  The purpose of this scope is to include only document items in the search results; which is one of the most commonly performed searches.  I'm sure you have run into it; you search for a document and many other types of information are returned.  Using the All Sites scope includes sites, lists and anything else that matches your search criteria.  Adding the All Documents search scope to your Intranet will make a lot of users quite happy.

    In this article, I will show you how to create the All Documents search scope then configure it for use in the Search Center.

    The key to creating our search scope can be found by using one of the many content class identifiers provided out of the box; Microsoft has created a bunch of these cryptic classifications for us (see the table below).  The content classification we will be using for our All Documents scope is "STS_ListItem_DocumentLibrary".  This content classification is applied to all items in every document library associated with indexed content.  Creating a scope using this classification will result in a set of content that only includes document library items; pretty cool huh!

    Content Class Identifier Description
    STS_Web Site
    STS_List_850 Page Library
    STS_ListItem_850 Pages
    STS_List_DocumentLibrary Document Library
    STS_ListItem_DocumentLibrary Document Library Items
    STS_List_Links Links List
    STS_ListItem_Links Links List Items
    STS_List_Tasks Task List
    STS_ListItem_Tasks Task List Items
    STS_List_Events Events List
    STS_ListItem_Events Events List Items
    STS_List_Announcements Announcements Lists
    STS_ListItem_Announcements Announcements List Items
    STS_List_Contacts Contacts Lists
    STS_ListItem_Contacts Contacts List Items
    STS_ListDiscussionBoard Discussion Board Lists
    STS_ListItem_DiscussionBoard Discussion Board List Items
    STS_List_IssueTracking Issue Tracking Lists
    STS_ListItem_IssueTracking Issue Tracking List Items
    STS_List_GanttTasks Project Task Lists
    STS_ListItem_GanttTasks Project Task List Items
    STS_List_Survey Survey Lists
    STS_ListItem_Survey Survey List Items
    STS_List_PictureLibrary Picture Libraries
    STS_ListItem_PictureLibrary Picture Library Items
    STS_List_WebPageLibrary Web Page Libraries
    STS_ListItem_WebPageLibrary Web Page Library Items
    STS_List_XMLForm Form Libraries
    STS_ListItem_XMLForm Form Library Items
    STS_List Custom Lists
    STS_ListItem Custom List Items

    Scopes in SharePoint can be created and managed in two (2) places; either at the farm level or at the Site Collection level.  To create scopes at the farm level, you need to have access to Central Administration.  Once created using Central Administration, the scope can be used in any Site Collection.  It is very common for the All Documents scope to be created at the farm level.  However, for the purposes of this article, I will demonstrate creating the scope at the Site Collection level.  There are many who don't have access to Central Administration and I didn't want you to feel left out!

    Follow the steps below to create a new search scope named All Documents.

    Note - you must be a Site Collection administrator to perform these steps!

    1. In your Site Collection, go to the top-level site.  Click the Site Actions -> Site Settings -> Modify All Site Settings menu.
    2. From the Site Settings page, in the Site Collection Administration group, click the Search scopes link.
    3. From the View Scopes page, click the New Scope link.
    4. From the Create Scope page, for the Title, type All Documents.
    5. Select both checkboxes in the Display Groups section.  This will make the scope available in the Search Dropdown and Advanced Search page.
    6. Click the OK button.
    7. From the View Scopes page, locate your new All Documents scope, click the associated Add rules link.
    8. From the Add Scope Rule page, for the Scope Rule Type, select the Property Query option.
    9. In the Add property restrictions dropdown, select the contentclass option.
    10. For the contentclass value, enter STS_ListItem_DocumentLibrary.
    11. Click the OK button when done.

    All Documents Scope Rule - Click for Larger Image
    All Documents Scope Rule

    The hardest part of this exercise is now complete!  You may have to wait until SharePoint builds the scope using the new rules.  This will be indicated on the View Scopes page.

    View Scopes - Click for Larger Image
    New All Documents Scope

    The next thing we need to do is configure the Search Center so our new All Documents scope is visible; similar to the All Sites and People scopes.  One thing you may notice in the images above/below, I have changed the All Sites scope to All Content.  This is also a common change we make; seems to make more sense to the non-technical user.

    There are a lot of steps required to configure a new tab and scope in a Search Center; make sure to follow them closely as to not miss something!

    Before anything else, navigate to your Search Center; typically the site titled Search.

    Creating the All Documents Search Page

    1. From your Search Center site, click the Site Actions -> Create Page menu option.
    2. From the Create Page page, for the Title, enter All Documents.
    3. The URL Name should already contain AllDocuments.  If it doesn't, make sure to change it.
    4. For the Page Layout, select the Search Page option.
    5. Click the Create button.

    Adding the All Documents tab to the Search Page

    1. From the new All Documents page, click the Add New Tab link.
    2. From the Tabs in Search Pages: New Item page, for the Tab Name, enter All Documents.
    3. For the Page, enter AllDocuments.aspx.
    4. Click the OK button.

    Updating the Search Web Part to Redirect Results to the AllDocumentResults.aspx Page

    1. From the new All Documents page, on the Search Box Web Part, click the edit -> Modify Shared Web Part context menu option.
    2. In the Search Box Web Part properties, expand the Miscellaneous section.
    3. Scroll down an locate the Target search results page URL property and enter AllDocumentResults.aspx.
    4. Click the OK button to save the Web Part property changes.

    Creating the All Document Results Page

    1. From your Search Center site, click the Site Actions -> Create Page menu option.
    2. From the Create Page page, for the Title, enter All Documents.
    3. The URL Name change it to AllDocumentResults.
    4. For the Page Layout, select the Search Results Page option.
    5. Click the Create button.

    Adding the All Documents tab to the Search Results Page

    1. From the new All Documents (results) page, click the Add New Tab link.
    2. From the Tabs in Search Results: New Item page, for the Tab Name, enter All Documents.
    3. For the Page, enter AllDocumentResults.aspx.
    4. Click the OK button.

    Updating the Search Web Part to Redirect Results to the AllDocumentsResults.aspx Page

    1. From the new All Documents (results) page, on the Search Box Web Part, click the edit -> Modify Shared Web Part context menu option.
    2. In the Search Box Web Part properties, expand the Miscellaneous section.
    3. Scroll down an locate the Target search results page URL property and enter AllDocumentResults.aspx.
    4. Click the OK button to save the Web Part property changes.

    Updating the Search Core Results Web Part to Use Our New All Documents Scope

    1. From the new All Documents (results) page, on the Search Core Results Web Part, click the edit -> Modify Shared Web Part context menu option.
    2. In the Search Core Results Web Part properties, expand the Miscellaneous section.
    3. For the Search Scope property, enter All Documents.
    4. Click the OK button to save the Web Part property changes.

    Search Center with All Documents Scope - Click for Larger Image
    Search Center with All Documents Scope Configured

    You should now have a Search Center with a new scope tab labeled All Documents.  Its time to give it a try.  Click on the All Site (or All Content) scope tab and enter a search term.  Take a look at the search results; they will contain sites, pages, lists and everything else that matches your search term.  Now click the All Documents scope tab and look at the difference.  If you configured everything correctly, you should now only see documents that match your search term.

    Pretty cool huh!


    Posted Feb 19 2009, 02:19 AM by Bob Mixon

    SharePoint JavaScript Lib - SPJsLib发布

    之前在某个不能使用任何后台代码的项目中开始研究的用javascript去控制SharePoint,略有心得,也曾经在赏梅斋的moss开发群里做过一次和这个话题相关的讲座,记录点击这里

    前一阵整理了一下这个项目里用到的一些javascript的方法,并随着后面的几个项目添加了一些新的内容进去,现在发布出来。

    地址是:http://www.codeplex.com/SPJsLib

    主要是基于jQuery这个javascript库来做的,我做的时候和测试的时候jQuery还是1.2.6版本,现在已经是1.3.1了,在项目的release里也包含了一个1.2.6版本经过压缩的jQuery文件。

    使用的时候不需要对jQuery有了解,当然如果了解jQuery的话更快速的实现更丰富的功能。

    具体的使用方法参考项目网站里的文档(word 2003格式,中文的,几乎每个方法都有sample code,代码里的注释都是英文的),这里大概介绍一下这个库的作用:

    这个JavaScript库大致分成两大部分:

    第一部分:访问SharePoint内容

    通过AJAX技术(jQuery提供了很方便的跨浏览器的AJAX解决方案),调用SharePoint内置的Web Services,读取、查询、添加、修改或删除列表中的条目。此外还支持了对当前用户的用户配置文件中各个属性的读取(这是某个项目的产物)

    比如,下面这段简短的代码可以更新myList列表中所有lookup字段查阅了ID为19的条目的标题(来自文档):

       1: var res = queryItems('myList', "<Where><FieldRef Name='lookup' LookupId='TRUE'/><Value Type='Lookup'>19</Value></Where>", ['ID']); 
       2: var ids = []; 
       3: $.each(res.items, function(idx, item){ 
       4:     ids.push(item['ID']);        // $.each是jquery中的方法,效果类似于C#中的foreach 
       5: }); 
       6: var updateRes = updateItems('myList', ids, {'Title':'These are items lookup 19!'}); 
       7: alert(updateRes.success);

    第二部分:控制SharePoint表单

    这个表单指的是列表的新建和编辑表单,支持的字段类型包括:

    单行文本、多行文本(纯文本和带格式的文本)、数字(普通和百分比)、货币、选项(下拉列表、Radio、多选)、查阅项(单选、多选)、时间和日期(仅日期和带时间)、是/否、人员和组(不完全支持)、超链接、图片

    提供的功能包括:

    1、隐藏/只读字段

    2、获取/设置字段的值

    3、级联两个选项(下拉列表)类型的字段

    4、级联两个查阅项类型的字段

    5、为查阅项和选项(下拉列表)提供筛选功能(如果比较多的话选起来会方便很多)

    6、从客户端检测字段是否为空(和字段的那个设置无关,甚至可以根据某个字段的设置来决定是否要检查某些字段,文档中有个例子)

    7、重定义“确定”和“取消”按钮的行为

    这两部分内容结合起来,不用任何C#代码也能够完成很多操作了。当然,最好对javascript有一定的了解(不需要对jQuery有了解,当然了解更好)。

    文档中的两张图(查阅项字段的级联和筛选):

    clip_image002

    clip_image002[9]

    只读部分字段的效果:

    image

    如果有任何问题或者建议的话可以在blog上或者codeplex上反馈给我,欢迎试用(已经在IE6/IE7/FF3.0上经过了初步测试)~

    posted on 2009-02-03 01:16:04 by erucy  评论(2) 阅读(3402)

    页面库无法捕获到Added事件?

    标题党一下。

    问题发生在一个文档库(文档模板是“空白页”)中,写了一个Added的事件处理程序,把标题字段改成文件名(不带扩展名的),但是发现新建页面的时候(不是上载)没效果。难道没有捕获到Added事件?

    经过单点调试,发现事件是捕获到了,因为里面抛出一个异常导致没有正常执行。

    很奇怪的问题:在Added事件中,properties.ListItem居然是null!(ListItemID是0),一般而言只有在Adding的时候才是null(因为Adding时条目还没有真正被创建出来),不知道是不是SharePoint的bug,不知道是不是在某些hotfix更新过了(我对hotfix的跟踪不是很及时。。。),也不知道在其他文档模板的情况下有没有问题。

    解决方法是这样的:

       1: using(SPWeb web = properties.OpenWeb())
       2: {
       3:   SPFile file = web.GetFile(properties.AfterUrl);
       4:   SPListItem item = file.Item;
       5:   // do something with the item
       6: }

    可以看到,AfterUrl是可以拿到这个新页面的地址的,而且可以正常拿到文件和条目,说明在Added的这个时候条目已经出现了,但是为什么直接用properties.ListItem拿不到呢?有时间的话可以去挖掘一下……

    posted on 2009-02-17 17:47:02 by erucy  评论(1) 阅读(2347)

    Windows Server 2008之AD RMS详细部署步骤

    2009-04-25 11:53 来源:比特网论坛 作者:佚名 【网友评论0发言

    0

    点击分享

    Windows Server 2008之AD RMS详细部署步骤(图)

      活动目录权利管理服务(AD RMS-Windows Server Active Directory Rights Management Services)是一种信息保护技术,与AD RMS激活的应用一起保障数字信息不受未授权的使用。内容拥有者可以确切定义接收者如何使用这些信息,如谁可以打开、修改、打印、转发或使用邮件或文件进行其他活动。公司可以创建自定义使用权利模版,如只可以直接用于如财务报告、产品说明、顾客数据以及电子邮件信息等信息的”机密-只读”模版。

      AD RMS内建于Windows Server 2008系统,相对于2003下的RMS有了较大的改进与提升,例如:不需要单独下载即可安装、不再需要连接到Microsoft去进行登记等等。

      AD RMS服务器和客户端系统处理过程,第一步:开始发行用户许可申请AD RMS内容许可。一旦有个用户通过RMS服务器已经发出一份账户证书,用户可以保护内容。这使文档的RMS保护变得简单;RMS特点是内置到微软的应用产品,例如微软office word和微软office Excel。RMS服务器绑定的权利的信息内容和加密内容,以防止未经授权的访问。当用户试图查看或以其他方式使用受保护文档时,RMS服务器发出声响,并检查用户的权限,发出解密和使用许可。

      在Windows Server 2008之前,一个外部用户需要进入RMS保护的内容必须有一个本地用户帐户。在简化外部帐户管理后,这已经不再需要。

      在安装之前的准备工作当然是不能少的,域环境的支持、在为RMS准备一个账户给其管理员的权限,由于部署的时候特别的简单,下面就不用文字标明了,大家看图吧!

    相关文章|

    Upload bug in MOSS 2007 / Windows Server 2008

    Filed Under (SharePoint, SharePoint administration) by Boris Gomiunik on 09-02-2009

    With the new installation of MOSS 2007 on Windows Server 2008 you might run into a slight bump when trying to upload large files – to be more precise – files larger than 28 MB. Even though you’ve increased the maximum upload limit in SharePoint central administration, the upload still doesn’t work. Here are some symptoms that I received:

    • Page cannot be found error in Internet Explorer when trying to upload to MOSS document library through “Upload” button
    • Document not displaying in document library after uploading with “Upload multiple files” button even though the upload went to 100%
    • Windows delayed write failed when trying to upload document through Explorer view. After the error the file appears in document library, but it has a file size 0.

    The error is not in SharePoint, the error is in IIS7 which limits the upload to 28 MB. To remove this limitation I’ve followed instructions from the KB article:

    Error message when you try to upload a large file to a document library on a Windows SharePoint Services 3.0 site: “Request timed out”

    Just in case: this did the trick: add the following lines at the end of your web’ application’s web.config file – just before the </configuration> closing tag:

    <system.webServer>
      <security>
        <requestFiltering>
          <requestLimits maxAllowedContentLength="2147483648"/>
        </requestFiltering>
       </security>
    </system.webServer>

    image

    Syncing WSS and MOSS User profile properties with Active Directory

    Posted by Christian Dam on May 5, 2008

    Have you ever experienced that the properties from the Shared Services User Import are not correctly replicated to your existing sites?

    Let me illustrate! From a “clean” MOSS installation with user profile import correctly configured, when you from the Welcome drop down list choose My Settings all you see is this:

    If you look at the same account in the Shared Services Provider, it also has no properties:

    This is expected at the user account in Active Directory also has no properties set. Let’s enter some:

    After having run a full import the MOSS profile is populated with the properties from Active Directory:

    So far so good, right? Almost! The My Settings information is still not reflecting the changes. 

    Rachel explained this in the MSDN forum:

    “There are actually 2 user profiles – one is a WSS profile and one is a MOSS profile. The WSS profile you access from Welcome user > My Settings page. The MOSS profiles are created when users are imported into the system from AD or LDAP. They are access from People Search or from a link off of your MySite.

    The reason there are 2 is that you can install WSS without MOSS and they wanted a basic user profile. If you installed WSS without MOSS, you would see the profile (again, accessed through Welcome user > My Settings page) with about 3 properties.

    If you install MOSS, do an import, and go to the WSS profile, you’ll see a bunch of properties added that MOSS adds. We now depricate the WSS profile. If you want to add property values to your profile, you need to go to your MOSS profile from your MySite (MySite > Details). You’ll be on the editprofile.aspx page. Add your properties. We then sync your properties to the WSS user list. You will see the values show up on the WSS profile after the sync happens.”

    So the question is how to to force the replication?

    Well, two MOSS Timer jobs per Web Application apparently control the replication. If you take a look at the Timer Job definitions (Central Administration -> Operations -> Timer Job definitions), you’ll find jobs called Profile Synchronization and Quick Profile Synchronization. These jobs should sync the changes to the WSS profiles. Unfortunately simply wait for the jobs to run aren’t good enough. However, a server reboot will make the synchronization happen. It is a bit drastic to reboot the server simply just to force MOSS/WSS to update a property update!

    To make a long story short, use stsadm -o sync to force the property sync:

    • -o -synctiming changes the Profile Sync job
    • -o -sweeptiming changes the Quick Profile Sync job

    I have gotten the best results by changing the schedule for the Profile Sync job to run every couple of minutes (stsadm -o sync -synctiming m:2). This may not be appropriate in a production environment with a large user population, though.

    Update:

    A great post explaining variuos aspects about user profiles and how they relate can be found here. Another great post about the sync jobs and user profile properties can be found here.

    Update 2:

    As stated by a few people in the comments, the trick with changing the synctiming and sweeptiming settings does not always work. I had the same issue at a customer site recently where not matter what I did, the profiles wouldn’t sync. I event tried to restart the Timer Job Service and the entire server farm, as I seen it work in other situations. Unfortunately, it didn’t work either.

    However, the problem was solved using the stsadm -o sync -listolddatabases <n> and stsadm -o sync -deleteolddatabases <n> commands. The listolddatabases <n>option will list the databases that have not been successfully syncronized the last <n> days, and the deleteolddatabases <n>option will delete the syncronization information from the databases that are not successfully syncronized the last <n> days. Have no fear, using the deleteolddatabases option will not delete the content databases.

    Afted having deleted the old sync information I forced the timer jobs to run as described above, and the syncronization completed successfully.

    If you are having sync issues, chances are that error messages are showing up in the event log. Rodney Langley has a great post we he talks about similar issues as described in this Update here

    Writing c# inline code in default.master

    A few people have posted on the SharePoint newsgroups about writing inline c# code in SharePoint 2007 masterpages. I’m certainly not saying this is a best practise, and there are many different ways to skin a cat, but if you do want to add inline c# into default.master or any other masterpage (or content layout page), these are the basic steps.

    Open up SharePoint Designer and the masterpage you want to edit. Switch to the code view and anywhere from the first <head> tag down you can add some inline c# code:

    <script runat="server">
        string myVar = "hello world!";
        void Page_Load(object sender, System.EventArgs e)
        {
            Response.Write(myVar);
            SPSite siteCollection = new SPSite("http://usb-server1");
            SPWeb site = siteCollection.OpenWeb("/SiteDirectory/MainCalendar/");

            SPList list = site.Lists["Announcements"];
            SPListItemCollection items = list.Items;

            foreach(SPListItem item in items)
            {
                Response.Write(item["Title"].ToString());
                Response.Write("<br/>");
            }

        }
    </script>
    Doesn’t do anything amazing but does show you can use the SharePoint object model in your inline code. If you saved the masterpage now and opened the site in your browser you’d get an error about not being able to run code blocks. There’s an extra line you need to put into your web.config file first to allow this inline c# to execute.

    <PageParserPaths>
            <PageParserPath VirtualPath="/_catalogs/masterpage/*" CompilationMode="Always" AllowServerSideScript="true" IncludeSubFolders="true" />
    </PageParserPaths>

    The PageParserPaths xml tags will be there already you just need to add the line in between. Save web.config and off you go. Your pages will render properly and the c# inline code will execute.

    Again I’d like to point out that this is possibly not good practise. The fact that CompilationMode being set to ‘Always’ points out that there may be a performance hit and cache’ing won’t exactly work well. But if you need to, that’s how to do it.

    Thanks to Ben Robb for discussing this on messenger with me. Ben should have his own blog soon and I know he’s got some great stuff to post.

    Ref: http://weblog.vb-tech.com/nick/archive/2006/08/03/1710.aspx

    Sample Code for Custom C# MOSS Navigation Using PortalSiteMapProvider

    So, The Mossman commented on my post yesterday saying that a little source around the PSMP would be nice, so just for him, here it is.  I figured it would be good to build on Andrew Connell's Telerik MOSS Integration Guide, so this example shows how to create your own top-level menu in a custom server-control using the Telerik RadMenu and the PortalSiteMapProvider.  I know not everybody will have the license for the Telerik RadMenu, so if you don't, hopefully you'll be able to take this example and pull out of it what you need.

    Also, I posted this post on top of the one yesterday, whoops.  There's a good lesson on locally saving your postings. Sorry if it's shown up new a couple of times for some of you. Wish I could figure out why...

    This solution shows how you could add custom attributes on each RadMenuItem from SPField values in the PublishingPage along with a custom client-side script event handler.

    Download the source for the complete control in a text file, if you'd like it.

    The menu created will look like the following and will pop a JavaScript alert with the relevant PublishingPage and SPWeb GUIDs when clicked:
    PSMP_Menu

    protected override void CreateChildControls() { //Get the root publishingweb web for the site PublishingWeb rootWeb = PublishingWeb.GetPublishingWeb(SPContext.Current.Site.RootWeb); //Get the URL of the default page in the web string defaultPageUrl = rootWeb.DefaultPage.ServerRelativeUrl; //find the item in the PSMP PortalListItemSiteMapNode smnHome = (PortalListItemSiteMapNode)PortalSiteMapProvider.

    CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(defaultPageUrl); //initialize the RadMenu RadMenu menu = new RadMenu(); menu.ID = "MainMenu"; menu.RadControlsDir = "/_wpresources/RadMenu.Net2/4.3.2.0__bbe59a8ad3533e68/RadControls"; menu.Skin = "Outlook"; //Set the client-side clicked event handler menu.OnClientItemClicked = "MainMenu_RadMenuItemClicked"; //create the first menu item for the default (home) page RadMenuItem rmiHome = createMenuItem(smnHome); menu.Items.Add(rmiHome); //iterate through each one of the pages and subsites and create menu items for them foreach (SiteMapNode smnTopLevelItem in smnHome.ParentNode.ChildNodes) { RadMenuItem rmiTopLevelItem = createMenuItem(smnTopLevelItem); //if the current sitemap has children, create a submenu for it if (smnTopLevelItem.HasChildNodes) { foreach (SiteMapNode smnChildItem in smnTopLevelItem.ChildNodes) { RadMenuItem rmiChildItem = createMenuItem(smnChildItem); rmiTopLevelItem.Items.Add(rmiChildItem); } } menu.Items.Add(rmiTopLevelItem); } this.Controls.Add(menu); //create the client-side script for the RadMenuItemClicked event handler StringBuilder sbScript = new StringBuilder(); sbScript.Append(Environment.NewLine + "<script language=\"javascript\">"); sbScript.Append(Environment.NewLine + "function MainMenu_RadMenuItemClicked(sender, eventArgs)"); sbScript.Append(Environment.NewLine + "{"); sbScript.Append(Environment.NewLine + "var pageGuid = eventArgs.Item.GetAttribute(\"PageGuid\");"); sbScript.Append(Environment.NewLine + "var webGuid = eventArgs.Item.GetAttribute(\"WebGuid\");"); sbScript.Append(Environment.NewLine + "alert(\"WebGuid:\" + webGuid + \" PageGuid:\" + pageGuid);"); sbScript.Append(Environment.NewLine + "}"); sbScript.Append(Environment.NewLine + "</script>"); this.Page.ClientScript.RegisterStartupScript(typeof(string), "RadMenu_MainMenu_RadMenuItemClicked", sbScript.ToString()); } /// <summary> /// Create a RadMenuItem from a SiteMapNode /// </summary> /// <param name="siteMapNode">SiteMapNode used to create RadMenuItem </param> /// <returns>RadMenuItem</returns> private RadMenuItem createMenuItem(SiteMapNode siteMapNode) { RadMenuItem menuItem = new RadMenuItem(); menuItem.NavigateUrl = siteMapNode.Url; menuItem.Text = siteMapNode.Title; SPListItem listItem = null; //if the SiteMapNode is the default page, it will be a PortalWebSiteMapNode if (siteMapNode is PortalWebSiteMapNode) listItem = getListItemFromPortalSiteMapNode((PortalWebSiteMapNode)siteMapNode); if (siteMapNode is PortalListItemSiteMapNode) listItem = getListItemFromPortalSiteMapNode((PortalListItemSiteMapNode)siteMapNode); //create the custom attributes on the list item if (listItem != null) { menuItem.Attributes.Add("PageGuid", listItem.UniqueId.ToString("N")); menuItem.Attributes.Add("WebGuid", listItem.Web.ID.ToString("N")); menuItem.ToolTip = listItem.Fields["MenuItemToolTip"].GetFieldValueAsText(listItem["MenuItemToolTip"]); } else { menuItem.Attributes.Add("PageGuid", string.Empty); menuItem.Attributes.Add("WebGuid", string.Empty); menuItem.ToolTip = siteMapNode.Title; } return menuItem; } private SPListItem getListItemFromPortalSiteMapNode(PortalListItemSiteMapNode siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = pubWeb.PagesList.Items[siteMapNode.UniqueId]; return pageItem; } private SPListItem getListItemFromPortalSiteMapNode(PortalWebSiteMapNode siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = null; if(pubWeb.DefaultPage != null) pageItem = pubWeb.PagesList.Items[pubWeb.DefaultPage.Item.UniqueId]; return pageItem; }

    Custom Auditing In SharePoint

    Browse the Code Online

    Contents

    The AuditingDemo Project
    Creating a Page to Support Auditing Configuration
    Extending the Site Actions Menu
    Viewing Audit Log Entries
    Viewing Logs on a Per-Item Basis

    Many people using SharePoint® technologies don't realize that there is auditing support built directly into the Windows® SharePoint Services (WSS) 3.0 platform. The primary reason this is not well-known is that WSS auditing support is turned off by default, and it cannot be enabled using anything supplied by WSS out of the box. Taking advantage of the WSS auditing infrastructure requires extra code that is not included with WSS.

    One simple way to take advantage of WSS auditing support is to use Microsoft® Office SharePoint Server (MOSS) 2007. MOSS provides a user interface (under Site Settings > Configure Audit Settings) that allows a site-collection owner to enable and configure automatic activity event logging. MOSS also provides an audit-reporting facility that reads audit log entries and reports on which users have been engaging in activities, such as reading and writing content, within a specific site collection.

    A second approach to using WSS auditing support will appeal to you as a developer. You can build a custom SharePoint solution with Visual Studio® and create a custom application page that allows a site-collection administrator to enable and configure WSS activity event logging. But it's not enough just to turn on automatic activity event logging. It requires more than that. A custom auditing solution targeting WSS must also include some type of user interface so that users can view or report on audit entries that have been added to the WSS audit log.

    Two years ago, not long after Microsoft released the first public beta for MOSS 2007, Joanna Bichsel and I published a white paper titled "Item-Level Auditing with SharePoint Server 2007" (msdn.microsoft.com/library/bb397403), along with an accompanying code sample. In this white paper, we discussed many important details about how to program auditing support in WSS. We also covered how MOSS leverages and extends the WSS auditing infrastructure using custom policies and audit report generation.

    In this month's column I am going to walk through a new SharePoint solution I recently created with a Visual Studio project named AuditingDemo. The project contains some of the same auditing management code I covered in the white paper, such as the code that enables auditing support through the WSS object model. However, the AuditingDemo project has been totally redesigned and is a much better starting point than the sample code I wrote two years ago. For example, the AuditingDemo project has been created using the STSDEV utility, and I have incorporated many best practices in areas such as solution-package deployment, security programming, and security trimming.

    My goal with this month's column is to explain these updated best practices and SharePoint development techniques. It is my intention to complement the original white paper rather than overlap its content. If you have not read the original white paper, I recommend taking a look at it first so that you have a proper context for this month's column.

    The AuditingDemo Project

    The purpose of the AuditingDemo project is to provide a custom SharePoint solution that can take advantage of the auditing support built into the WSS platform. I designed the project around a scenario wherein a site-collection owner (or another user in the role of Audit Manager) can enable, view, and modify audit settings for the current site collection. The AuditingDemo project also provides viewing capabilities so that a user in the role of an auditor can see what's in the audit log to determine what activity has occurred on a site-collection-wide basis and also on a per-item or per-document basis.

    As I mentioned earlier, this project was built using the STSDEV utility, which you can download from codeplex.com/stsdev. You can read about it in my March 2008 Office Space column (msdn.microsoft.com/magazine/cc337895).

    The AuditingDemo project has been designed with a central feature (also named AuditingDemo) that is scoped to the level of the site collection. To use the AuditingDemo, you simply need to activate the feature once per site collection.

    The AuditingDemo feature includes a feature receiver class with a FeatureActivated event handler (see Figure 1). The code inside FeatureActivated executes during feature activation, and it accomplishes two important things. First, it fully enables audit logging for the entire site collection. Second, it creates a few security objects specific to the AuditingDemo solution. In particular, the code inside FeatureActivated creates two new SharePoint groups and two new permission levels that allow the site-collection administrator to add users into the roles of Auditor and Audit Manager.

    Figure 1 The FeatureActivated Event Handler

    Copy Code

    public override void FeatureActivated(SPFeatureReceiverProperties 
      properties) {
      using (SPSite siteCollection = (SPSite)properties.Feature.Parent) {
        SPWeb TopLevelSite = siteCollection.RootWeb;
    
        // Turn on auditing flags.
        siteCollection.Audit.AuditFlags = SPAuditMaskType.All;
        siteCollection.Audit.Update();
    
        // create permission levels 
        SPRoleDefinition AuditorPermissions, AuditManagerPermissions;
        AuditorPermissions = CreatePermissionLevel(
          "Auditor Permissions", 
          "Can view audit logs",
          "Read");
        AuditManagerPermissions = CreatePermissionLevel(
          "Audit Manager Permissions", 
          "Can configure auditing support",
          "Design",
          SPBasePermissions.ManageWeb);
    
        // create Auditors group
        SPGroup Auditors = CreateGroup(
          "Auditors", 
          "for users who need to audit user activity");
        SPRoleAssignment AuditorRoleAssignment = new SPRoleAssignment(Auditors);
        AuditorRoleAssignment.RoleDefinitionBindings.Add(AuditorPermissions);
        TopLevelSite.RoleAssignments.Add(AuditorRoleAssignment);
    
        // create Audit Managers group
        SPGroup AuditManagers = CreateGroup(
          "Audit Managers", 
          "for users who configure WSS auditing support");
        SPRoleAssignment AuditManagerRoleAssignment = 
          new SPRoleAssignment(AuditManagers);
        AuditManagerRoleAssignment.RoleDefinitionBindings.Add(
          AuditManagerPermissions);
        TopLevelSite.RoleAssignments.Add(AuditManagersRoleAssignment);
    }
    

    Note that the code in the FeatureActivated event handler calls the two utility methods named CreatePermissionLevel and Create­Group. The reason I wrote these was to ensure that any preexisting security objects with the same name as those being created were first deleted. Each method then creates the requested security object (permission level or group), adds it to the appropriate collection within the top-level site, and returns a strongly typed security object to the caller. The CreatePer­missionLevel method returns an SPRoleDefinition object that represents the new permission level, and the CreateGroup method returns an SPGroup.

    Note that I designed the CreatePermissionLevel method with several overloaded implementations that make the third and fourth parameters optional. The third parameter is for passing the name of an existing permission level that is used to make a copy for the new permission level. For example, the AuditorPermissions permission level is created by making a copy of the built-in Read permission level. And the AuditManagerPermissions permission level is created by making a copy of the built-in Design permission level.

    The fourth parameter to the CreatePermissionLevel method is of the SPBasePermissions type, which is used to pass one or more extra permissions that are then used to initialize the new permission level. For example, the call to CreatePermissionLevel that creates the SPRoleDefinition object AuditManagerPermissions passes a value of ManageWeb for the fourth parameter. This means that the new permission level is created with the same permissions as the built-in Design permission level plus the ManageWeb permission.

    The ManageWeb permission is important because it's required for users who need to adjust audit settings. I will cover two security trimming techniques later in this column that can be used to display menu items to just those users that have this permission.

    The CreateGroup method does a little more than add a new group to the top-level site. It also adds the new group to the associated group's collection and adds the ID of the new group into a site-level property named vti_associatemembergroup. This extra code is important if you want the new group to show up in the group's QuickLaunch bar and inside the combobox of the Add Users page, which makes it far more intuitive for the site-collection owner to add users to the new group.

    Creating a Page to Support Auditing Configuration

    The AuditingDemo project provides three custom app pages—AuditConfig.aspx, AuditLogViewer.aspx, and ItemAudit.aspx—that were developed using best-practice techniques. For example, these application pages are deployed within a solution-specific directory named AuditingDemo inside the LAYOUTS directory. The code that provides the behavior for these pages has been written in codebehind files (such as AuditConfig.cs). The codebehind files are then compiled into the project's main assembly, AuditingDemo.dll, which is installed and loaded from the Global Assembly Cache (GAC).

    The AuditConfig.aspx application page provides a user interface for configuring WSS auditing support. I added a CustomAction to the AuditingDemo feature so that users with the ManageWeb permission will be presented with a link on a site-settings page that allows them to navigate to AuditConfig.aspx:

    Copy Code

    <!-- Add Link to Site Setting Page -->
    <CustomAction
      Id="SiteActionsToolbar"
      GroupId="SiteCollectionAdmin"
      Location="Microsoft.SharePoint.SiteSettings"
      Sequence="0"
      Rights="ManageWebs"
      Title="Audit Management" >
      <UrlAction Url="~sitecollection/_layouts/AuditingDemo/AuditConfig.aspx"/>
    </CustomAction>
    

    Note that I created this custom action with a GroupId attribute value of SiteCollectionAdmin and a Sequence attribute value of 0. This is what makes the link show up first in the Site Collection Administration column of the Site Settings page.

    The Rights attribute, which I have included with a value of Manage­Webs, is used by WSS to provide declarative security trimming. Therefore, only users who have the ManageWebs permission will see this link. This will be the case for site-collection owners as well as any users that the site-collection owner has added to the role of Audit Manager.

    When users navigate to AuditConfig.aspx, they see the UI in Figure 2. As you can see, this application page provides radio buttons to fully enable or disable auditing. You will also find a radio button for entering a selective mode where the user can choose exactly what activities are recorded with an audit log entry.

    Figure 2 AuditConfig.aspx Lets Users Configure Audit Logging

    The code that is behind the OK button of AuditConfig.aspx is pretty simple. It reads which radio button has been selected by the user and sets the audit flags for the current site collection to the appropriate value. Then it calls Update on the Audit property to record the changes into the Content Database:

    Copy Code

    SPSite siteCollection = this.Site;
    if (radAuditingOff.Checked) {
      siteCollection.Audit.AuditFlags = SPAuditMaskType.None;
    }
    if (radAuditingOnFull.Checked) {
      siteCollection.Audit.AuditFlags = SPAuditMaskType.All;
    }
    if (radAuditingOnSelective.Checked) {
      siteCollection.Audit.AuditFlags = GetSelectiveAuditingFlags();
    }
    siteCollection.Audit.Update();
    

    If the user has chosen the option for selective auditing configuration, there is a call to the GetSelectiveAuditingFlags utility method. It inspects all those checkboxes and uses bitwise OR operations to return an SPAuditTypeMask value that represents a combination of all the types of activities that the user has selected for auditing:

    Copy Code

    private SPAuditMaskType GetSelectiveAuditingFlags() {
      SPAuditMaskType AuditFlags = SPAuditMaskType.None;
      if (chkAuditView.Checked) {
        AuditFlags |= SPAuditMaskType.View;
      }
      if (chkAuditUpdate.Checked) {
        AuditFlags |= SPAuditMaskType.Update;
      }
      // Repeat for Copy, Move, Delete, Undelete, CheckIn, CheckOut,
      // Search, Workflow, SecurityChange, ProfileChange, SchemaChange
      return AuditFlags;
    }
    

    Extending the Site Actions Menu

    I've provided navigation support so that users can get to the AuditLogViewer.aspx application page. This is a page designed for users in the role of auditor who want to see what activity has occurred on the site. I decided against putting another link on the Site Settings page because many of the users in the role of auditor may not necessarily be administrators and therefore may never go to the Site Settings page for any other reason. Therefore, adding navigation support using the custom Site Actions menu items seemed more intuitive. It also gives me a chance to show you how to create a flyout menu with programmatic security trimming.

    When you want to build a menu item dynamically, you need to create a custom control class and also add a declarative CustomAction element to instantiate an instance of the control class in the correct place. Note how the following CustomAction element differs from the one I showed earlier:

    Copy Code

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <!-- Add Command to Site Actions Dropdown -->
      <CustomAction Id="AuditingSupport"
        GroupId="SiteActions"
        Location="Microsoft.SharePoint.StandardMenu"
        Sequence="1000"
        ControlClass="AuditingDemo.SiteActionsCustomSubMenu"
        ControlAssembly="AuditingDemo, [4-part name]"
        Title="Auditing Support"
        Description="Support for configuring and viewing auditing" />
    </Elements>
    

    The main difference with this CustomAction element is that it has been declared using a ControlClass attribute and a Control­Assembly attribute instead of a UrlAction element. This makes it possible to generate menu items dynamically using a custom control class such as the SiteActionsCustomSubMenu, which is used in the AuditingDemo project and is shown in the code in Figure 3. Note that a custom control class must inherit from the WebControl class supplied by the ASP.NET programming model.

    Figure 3 SiteActionsCustomSubMenu

    Copy Code

    public class SiteActionsCustomSubMenu : WebControl {
    
      protected override void OnLoad(EventArgs e) {
        this.EnsureChildControls();
        base.OnLoad(e);
      }
    
      protected override void CreateChildControls() {
        SPSite siteCollection = SPContext.Current.Site;
        SPWeb site = SPContext.Current.Web;
        SPUser user = site.CurrentUser;
        // provide security trimming
        if (IsCurrentUserInGroup("Auditors") ||
            IsCurrentUserInGroup("Audit Managers") ||
            user.IsSiteAdmin) {
          string siteCollectionPath = siteCollection.Url;
          if (!siteCollectionPath.EndsWith(@"/"))
            siteCollectionPath += "/";
    
          SubMenuTemplate smt = new SubMenuTemplate();
          smt.Text = "Auditing Support";
          smt.ID = "mnuAuditingSupport";
          smt.Description = "Configure and View Auditing";
          smt.ImageUrl = siteCollectionPath +
                         @"_layouts/images/AuditingDemo/AfricanPith32.gif";
          smt.Sequence = 400;
    
          MenuItemTemplate mit1 = new MenuItemTemplate();
          mit1.ID = "mnuAuditLog";
          mit1.Text = "Audit Log";
          mit1.Description = "Inspect Audit Entries";
          mit1.Sequence = 401;
          mit1.ClientOnClickNavigateUrl = siteCollectionPath +
            "_layouts/AuditingDemo/AuditLogViewer.aspx";
          mit1.ImageUrl = siteCollectionPath +
            @"_layouts/images/AuditingDemo/Binoculars32.gif";
          // add menu item to Controls collection
          smt.Controls.Add(mit1);
          // perform extra security trimming for menu for AuditConfig.aspx
          if (IsCurrentUserInGroup("Audit Managers") || user.IsSiteAdmin) {
            MenuItemTemplate mit2 = new MenuItemTemplate();
            mit2.ID = "mnuAuditingConfiguration";
            mit2.Text = "Auditing Configuration";
            mit2.Description = "Enable/Disable Auditing";
            mit2.Sequence = 402;
            mit2.ClientOnClickNavigateUrl = siteCollectionPath +
              "_layouts/AuditingDemo/AuditConfig.aspx";
            mit2.ImageUrl = siteCollectionPath +
              @"_layouts/images/AuditingDemo/Compass32.gif";
            smt.Controls.Add(mit2);
          }
    
          this.Controls.Add(smt);
        }
      }
    
      private bool IsCurrentUserInGroup(string GroupName) {
        SPWeb site = SPContext.Current.Web;
        foreach (SPGroup group in site.SiteGroups) {
          if (group.Name.Equals(GroupName)) {
            return group.ContainsCurrentUser;
          }
        }
        throw new ApplicationException("There is no group named " + 
          GroupName);
      }
    }
    

    The CreateChildControls method provides dynamic security trimming. Note that the entire flyout menu is only shown to users who are either site-collection owners or who have been added to the Auditors or Audit Manager groups. The second menu item, which allows a user to navigate to the AuditConfig.aspx page, is further trimmed to exclude users in the Auditors group. This menu is only displayed to site-collection owners or users who have been added to the Audit Manager group.

    There is one more important point I want to make about creating a dynamic menu with a custom control class. Like a Web Part, a custom control class requires a SafeControl entry in the web.config file of the hosting Web application. Here, the STSDEV utility provides the support for adding this SafeControl. It adds the appropriate elements into the manifest.xml file, and, as a result, the required SafeControl entry is automatically added to one or more web.config files whenever the AuditingDemo.wsp solution package is deployed within a farm.

    Viewing Audit Log Entries

    The AuditingDemo solution provides the AuditLogViewer.aspx custom application page shown in Figure 4. This page provides the users with a view of all the audit entries for the entire site collection. There is also a button on this page with the caption Clear Audit Log. This button is security trimmed so it is only shown to site-collection owners. The code behind this button deletes all entries from the audit log, which you might find to be helpful while testing a custom auditing solution.

    Figure 4 AuditLogViewer.aspx Displays Audit Log Entries

    The code behind AuditLogViewer.aspx uses an SPAuditQuery object to query the audit log of the current site collection. A query is run by calling the GetEntries method on the Audit property of an SPSite object. A call to GetEntries returns an SPAuditEntry­Collection object that can be enumerated to inspect each audit entry as an SPAuditEntry object:

    Copy Code

      SPSite SiteCollection = SPContext.Current.Site;
      SPAuditQuery wssQuery = new SPAuditQuery(SiteCollection);
      SPAuditEntryCollection auditCol = 
        SiteCollection.Audit.GetEntries(wssQuery);
      foreach (SPAuditEntry entry in auditCol) {
        // enumererate through each audit entry
      }
    

    There are many ways in which you can enumerate through an SPAuditEntryCollection to create a display. I used a technique where I dynamically create an ADO.NET DataTable object and then populate it with one row of information per audit entry. By creating a DataTable, it becomes relatively simple to display the audit information by binding it to an SPGridView control.

    The code behind the AuditLogViewer.aspx page must deal with a special security concern. If you examine the code that queries the audit log, you will see that it first makes a call to RunWithElevated­Privileges so that it can run under the identity of the privileged SHAREPOINT\System account. Using this technique is required because querying the audit log is a privileged operation.

    There will likely be scenarios where a user is added into the role of Auditor, but this user will not be granted the permissions that are necessary in order to query the audit log. Therefore, a call to RunWithElevated­Privileges allows your code to query the audit log, even if the current user does not have the required permissions to do so.

    Viewing Logs on a Per-Item Basis

    The third application page in the AuditingDemo project is ItemAudit.aspx. This page shows audit entries for one particular item or document. Navigation to this page is provided by adding a CustomAction element that adds a new EditControlBlock (ECB) menu item to the built-in Item content type:

    Copy Code

       <CustomAction Id="ItemAuditing.ECBItemMenu"
         RegistrationType="ContentType"
         RegistrationId="0x01"
         ImageUrl="/_layouts/images/GORTL.GIF"
         Location="EditControlBlock"
         Sequence="300"
         Title="View Audit History">
           <UrlAction Url=
       "~site/_layouts/AuditingDemo/ItemAudit.aspx?ItemId=
       {ItemId}&amp;ListId={ListId}"/>
       </CustomAction>
    

    A CustomAction configured for the Item content type will also apply to any content types that inherit from Item. And since all content types inherit from the Item content type, this technique will effectively add an ECB menu item to every item and document across the entire site collection.

    You can test this technique out by downloading the AuditingDemo sample code and then deploying it within the farm on a SharePoint development machine. Once you have completed activation of the AuditingDemo feature in a particular site collection, you will see that every item and document now has an ECB menu item with a View Audit History title. Whenever a user selects that ECB menu item, he is redirected to the ItemAudit.aspx page, as shown in Figure 5.

    Figure 5 ItemAudit.aspx Displays Audit Entries for a Particular Item

    Like the AuditLogViewer.aspx page, the code behind ItemAudit.aspx uses an SPAuditQuery object to retrieve audit log data as well as a DataTable that is populated with audit log entry data and then bound to an SPGridView control. The main difference is that the code behind ItemAudit.aspx makes a call to the RestrictToListItem method of the SPAuditQuery object before running the query to filter the results so that they only pertain to the item or document in question.

    It's important to note that the SPAuditQuery class also provides two additional filtering methods, RestrictToList and RestrictToUser, so that you can see audit entries for a particular list or a particular user. Also note that you can use the RestrictToUser together with either the RestrictToListItem method or the RestrictToList method to determine what a specific user has been doing with either a list or a list item.

    Send your questions and comments for Ted to mmoffice@microsoft.com.

    Ted Pattison is an author, trainer, and SharePoint MVP who lives in Tampa, Florida, and has just completed his book Inside Windows SharePoint Services 3.0 for Microsoft Press. He also delivers advanced SharePoint training to professional developers through his company, Ted Pattison Group (www.TedPattison.net).

    JavaScript Item Menus Part 1 (Real World)

    I have had quite a few emails recently about ways of either hiding, showing, adding or modifying the item level menu items that appear within lists and document library. In this post I thought I would examine what you can do and what the best approach would be (in my opinion anyway). Firstly the bulk of the menu items are drawn from the “CORE.JS” file that resides in the “12” hive.

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\1033

    This file is a few thousand lines long so can be slightly cumbersome to work with. However the easiest way to find what you are after is to look at the name of the menu item you wish to change in UI and use this to search through the “CORE.JS”. For example I want to hide the “Send To” menu on all document libraries. To do this I would simply search the “CORE.JS” for the text “Send To”.

    Notice when I do it highlights the variable called “L_Send_Text”.

    Now call we have to do is search for that variable and hey presto we have found the function that is called when creating the menus.

    So using this example let’s look at completely hiding the send to menu items. This is quite a simple request but has to be done in a certain way. There are really a couple of ways of doing this. They are:

    1. Comment out the functions that are called within the CORE.JS

    2. Use a content editor web part and add this to the relevant pages (all of them)

    3. Use inline script within the Master Page

    Option 1 will work well, however where possible it is not best to modify the underline files when modifying MOSS2007. Option 2 is a favourite of mine but is very hard to maintain unless you are building custom list definitions for all your content. Also it is very hard to ensure that the web part is added to every list or library. Option 3 is the best option here, simply adding the functions as inline script code will mean that any page that calls this function will automatically call the function in the Master Page, not the CORE.JS.

    So let’s take option 2 for now just so we can see how this option works. The steps to take are:

    1. Comment out the “AddSendSubMenu” in the CORE.JS

    2. Add Content Editor Web Part to the “AllItems.aspx” page for the relevant list or library

    3. Add the “AddSendSubMenu” function to the Content Editor Web Part

    To comment out the function simply use the following at the beginning and the top of the function.

    Now we need to add the content editor web part to the relevant pages. We will open up a document library for this and select the “Edit Page” option from the site actions menu. Once the page is edit mode press the “Add a Web Part” button.

    Now we need to select the “Content Editor Web Part” to the page.

    Once it is on the page press the “Open Tool Pane” link within the web part and then press the “Source Editor” button. When the dialog opens add the following code:

    Once this added, if you select the item menu the “Send To” menu items will not appear.

    Ok, so not everyone will want to hide functionality but the principle is the same for each menu item. I have worked on a few projects where the “DELETE” menu item has either been moved or removed from the item menu and the list or library menu bar. So let’s look at adding it back but only the email link menu item. To do this we will change the code that exists in the content editor web part to be the following:

    When we now run the page the menu should then render as below:

    Let’s say we wanted to have an external process run from the menu item when we click a custom link. For example we might want to send the document to another system for processing or even copy the document somewhere else. This can be done quite easy by creating a new menu item and making the link a custom “aspx” page that contains our custom code. For this example we will simply pass a few query strings to custom page. To begin with let’s modify our code slightly.

    Now when we load the page it should render as below:

    I won’t show the code for the other page here, as you can really do whatever you want. The URL that we constructed in the JavaScript should now look as below:

    http://intranet.labs.local/StaffDirectory/_layouts/custompages/QueryStringExample.aspx?FileID=2&FileURL=http%3A%2F%2Fintranet%2Elabs%2Elocal/StaffDirectory/Team%20Documents/DemoDoc1.doc

    Notice that the variables that we created have now been populated. As you can see without knowing lots of complex c# or VB.Net you can create highly customisable menus within MOSS2007.

    Ref: http://www.helloitsliam.com/archive/2007/05/30/moss2007-%E2%80%93-javascript-item-menus-part-1-real-world.aspx

    Item Level Menus (Investigation)

    In some of the past posts I have done, I have spent some time showing you how to create new item level menus, using JavaScript and also using the "EditControlBlock" and feature framework. On a few projects I have worked on there has been a requirement to hide certain menu items from the item level menu. I have also had requirements to replace menus with our own custom ones, so for example the "Edit Properties" link will not use the default one but be hidden and then we re-create it bit with our own custom link. I decided to do some investigation on this and see what the best method was to use. The following methods will be used:

    1. "EditControlBlock" – If you can use it
    2. JavaScript – Modifications to the "CORE.JS"
    3. Custom JavaScript – Override the "CORE.JS"
    4. CSS – Create custom CSS to override the visibility of the menu items

    For those of you who have not yet looked into the "EditControlBlock" you can check out the following links:

    http://www.helloitsliam.com/archive/2007/07/24/moss2007-–-item-level-menus-using-"editcontrolblock".aspx

    http://www.helloitsliam.com/archive/2007/07/25/moss2007-–-item-level-menu-items-using-"editcontrolblock"-part-2.aspx

    http://blog.thekid.me.uk/archive/2007/06/23/sample-editcontrolblock-customaction-for-sharepoint.aspx

    http://sharepointnutsandbolts.blogspot.com/2007/07/using-customaction-to-modify-system.html

    http://sharepointnutsandbolts.blogspot.com/2007/07/modifying-system-pages-in-sharepoint.html

    So for this example I investigated whether or not the "EditControlBlock" could be used to hide menu items. Within the SDK for SharePoint and WSS you are told that you are able to create custom menus and also hide menu items by simply setting the "Location" value within the feature to "EditControlBlock". This framework works like a treat for creating menus and also hiding menu items that have been created using the custom action framework. However it does not seem to work when trying to hide the JavaScript drawn menus. So firstly for me to test this I needed to find the ID of the menu I wished to hide. This is done by opening the "CORE.JS" from the following location, C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033 and searching for the display name of the menu item you wish to hide. I want to hide the "Edit Properties" menu item. My search would be:

    Notice when I find this value it is assigned to a variable called "L_EditProperties_Text". This is the next value to search for.

    When it finds the value it should be the following block of code:

    What you should be able to see now is the following lines:

    These lines simply check whether or not the current list type is a document library of a list. If it is a document library it sets the ID to "ID_EditProperties", if it not is sets it to "ID_EditItem". Now we have our ID reference we can simply add this to our feature:

    After enabling this feature and checking the menu items it became evident that this did not work for the standard menus items that get drawn by the "CORE.JS". This is simply due to the fact that the menus are not drawn using the custom action framework. This is a shame really as it would make life slightly less complicated. The next option I looked at was simply modifying the "CORE.JS" directly. I would state at this point that you shouldn't really modify the actual files on the server, and always take a backup if you do. Also note that any changes you make you make to the "CORE.JS" will take effect on all the site collections on the server. To get round this simply copy the "LAYOUTS" directory and the "IMAGES" directory and rename them to match the site collection you are working with. Then re-map them within IIS to the correct web application and hey presto you can hack, I mean modify away and not affect any other site. So let's look at the "CORE.JS" again. We already have our section of code listed from above now all we have to do is comment out the rendering of the edit menu.

    When we now check the menu it should render as below:

    Notice that the "Edit Properties" menu item is now missing. After further investigation this option works perfectly every time. I am not a great fan of having to modify system pages but this does work 100% every time, you just need to have a semi-decent understanding of JavaScript to decipher the code. J

    So the next option was to use custom JavaScript to achieve the same, this option was a little more complicated as I found I was having to override the relevant functions and then re-write the "CORE.JS" functions I wanted from scratch. In this example I wanted to hide the "View Properties", "Edit Properties", and "Manage Permissions" menu items. Luckily for us these items are all drawn using one function shown below:

    So for this example I will add a content editor web part to the page and simply add some JavaScript into the page. The steps I followed for this example are listed below:

    1. Add "Shared Documents" to the front page of the site
    2. Add "Content Editor Web Part"
    3. Add custom JavaScript code to "CEWP"

    The menu items currently look as below:

    By adding the following JavaScript to the Content Editor Web Part it should remove certain items.

    The only issue I have found and this has not been tested on a different VM is sometimes when you move to a different page and then come back to it the custom JavaScript does not get called for some reason. An example of this is if I click the "Document Center" link:

    And then go back to the main page that runs my JavaScript it now renders the menu items as shown below and ignores my custom JavaScript.

    I don't get this issue when I do the same things on the actual document library pages it just seems to happen if you are trying to hide menu items using the document library (list view web part). Anyway there are ways of getting this to work but just takes a little more JavaScript. So as you can see this option works well and is an easy way of only having specific pages or sections of your site structure lose menu items. The last option actually came from having an email chat with "Andrew Connell". He suggested that maybe there might be a way of doing it using CSS (Cascading Style Sheets). I was intrigued by this as I hadn't even thought about using it. So to begin with I realised that I would need to create basic styles that map to the menu ID name we used earlier. I used the same principle as earlier and tested it by adding a CEWP to the page and adding CSS to it. So the page should look as below:

    Now we will look at hiding the "Manage Permissions" menu item. The ID for this menu is "ID_MngPerms". So within the CEWP I added the following:

    Now when I load the page and check the menu items it renders as below:

    As you can see from above the menu item is hidden but the image is still showing. This option always works though, not like the JavaScript that seems to not run, the CSS is always applied every time. At the moment I need to investigate the CSS option further so I can see why the image is showing. I have looked at the construction of the menu and from what I can tell it uses, "CORE.JS", "MENU.JS" and then uses "MENU.HTC" to draw these menu items. Currently I cannot find a way of hiding the whole row and not just the text. Might be me being a duffer, so if any CSS people know the answer let me know. J

    So what have I learned? Well out of the options I tested:

    1. "EditControlBlock" – If you can use it
    2. JavaScript – Modifications to the "CORE.JS"
    3. Custom JavaScript – Override the "CORE.JS"
    4. CSS – Create custom CSS to override the visibility of the menu items

    The only one that really works is actually modifying the "CORE.JS". The override option works well for adding menu items but not always for removing them. The CSS option would be great but still needs some investigation. It is a shame the "EditControlBlock" option does not work; it would have been nice if all the menu items were created using the custom action framework as against using JavaScript to render them. Anyway hope this is useful. As I investigate more I will post again.

    Ref: http://www.helloitsliam.com/archive/2007/08/10/moss2007-%E2%80%93-item-level-menus-investigation.aspx